73 votes

Comment créer une propriété de classe en lecture seule dans Python?

Essentiellement, je veux faire quelque chose comme ceci:

 class foo:
    x = 4
    @property
    @classmethod
    def number(cls):
        return x
 

Ensuite, j'aimerais que les tâches suivantes fonctionnent:

 >>> foo.number
4
 

Malheureusement, ce qui précède ne fonctionne pas. Au lieu de me donner 4 cela me donne <property object at 0x101786c58> . Y a-t-il un moyen de réaliser ce qui précède?

70voto

unutbu Points 222216

Cela rendra Foo.number un en lecture seule propriété:

class MetaFoo(type):
    @property
    def number(cls):
        return cls.x

class Foo(object):
    __metaclass__=MetaFoo
    x = 4

print(Foo.number)
# 4

Foo.number = 6
# AttributeError: can't set attribute

Explication: Le scénario habituel lors de l'utilisation de @property ressemble à ceci:

class Foo(object):
    @property
    def number(self):
        ...
foo = Foo()

Une propriété définie en Foo est en lecture seule à l'égard de ses instances. C'est, foo.number = 6 poserait un AttributeError.

De la même façon, si vous souhaitez Foo.number de soulever une AttributeError vous devez configurer une propriété définie en type(Foo). D'où la nécessité d'une métaclasse.

53voto

bobince Points 270740

Le descripteur property retourne toujours lorsqu'il est accédé depuis une classe (c'est-à-dire lorsque instance est None dans sa méthode __get__ ).

Si ce n'est pas ce que vous voulez, vous pouvez écrire un nouveau descripteur qui utilise toujours l'objet de classe ( owner ) au lieu de l'instance:

 >>> class classproperty(object):
...     def __init__(self, getter):
...         self.getter= getter
...     def __get__(self, instance, owner):
...         return self.getter(owner)
... 
>>> class Foo(object):
...     x= 4
...     @classproperty
...     def number(cls):
...         return cls.x
... 
>>> Foo().number
4
>>> Foo.number
4
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X