153 votes

Pourquoi @foo.setter en Python ne fonctionne pas pour moi?

Donc, je suis en train de jouer avec des décorateurs Python 2.6, et je vais avoir certaines difficultés à travailler. Voici mon fichier de classe:

class testDec:

    @property
    def x(self): 
        print 'called getter'
        return self._x

    @x.setter
    def x(self, value): 
        print 'called setter'
        self._x = value

Ce que j'ai pensé que cela signifie est de traiter l' x comme une propriété, mais d'appeler ces fonctions get et set. Donc, j'ai allumé au RALENTI et vérifier:

>>> from testDec import testDec
from testDec import testDec
>>> t = testDec()
t = testDec()
>>> t.x
t.x
called getter
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "testDec.py", line 18, in x
    return self._x
AttributeError: testDec instance has no attribute '_x'
>>> t.x = 5
t.x = 5
>>> t.x
t.x
5

Clairement le premier appel fonctionne comme prévu, depuis que j'appelle de la lecture, et il n'y a pas de valeur par défaut, et il échoue. OK, bon, je comprends. Toutefois, l'appel à attribuer t.x = 5 semble créer une nouvelle propriété, x, et maintenant de la lecture ne fonctionne pas!

Ce qui me manque?

301voto

nosklo Points 75862

Vous semblez être à l'aide de classique de style ancien classes. Afin de propriétés de fonctionner correctement, vous devez utiliser la nouvelle-classes de style plutôt (hérite de l' object). Il suffit de déclarer votre classe comme MyClass(object):

class testDec(object):

    @property
    def x(self): 
        print 'called getter'
        return self._x

    @x.setter
    def x(self, value): 
        print 'called setter'
        self._x = value


EDIT: il fonctionne. Je ne vois pas la raison de la downvotes.

>>> k = testDec()
>>> k.x
called getter
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/devel/class_test.py", line 6, in x
    return self._x
AttributeError: 'testDec' object has no attribute '_x'
>>> k.x = 5
called setter
>>> k.x
called getter
5
>>>

77voto

Andrew Hows Points 198

Juste une note pour les autres personnes qui trébuchent ici à la recherche de cette exception: les deux fonctions doivent avoir le même nom:

 @property
def x(self): pass

@x.setter
def x_setter(self, value): pass
 

va échouer avec la même exception.

22voto

MrTopf Points 2708

Vous devez utiliser des classes de nouveau style en dérivant votre classe de l'objet:

 class testDec(object):
   ....
 

Alors ça devrait marcher.

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