Donc, je joue avec des décorateurs en Python 2.6, et j'ai du mal à les faire fonctionner. 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 je pensais que cela signifiait, c'était de traiter x
comme une propriété, mais appelez ces fonctions sur get and set. Alors, j'ai lancé IDLE et l'ai vérifié:
>>> 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, puisque j'appelle le getter, et il n'y a pas de valeur par défaut, et cela échoue. OK, bien, je comprends. Cependant, l'appel à assigner t.x = 5
semble créer une nouvelle propriété x
, et maintenant le getter ne fonctionne plus!
Qu'est-ce que je rate?
Réponses:
Vous semblez utiliser des classes classiques de l'ancien style en python 2. Pour que les propriétés fonctionnent correctement, vous devez utiliser des classes de style nouveau à la place (en python 2, vous devez hériter de
object
). Déclarez simplement votre classe commeMyClass(object)
:Ça marche:
Un autre détail qui peut causer des problèmes est que les deux méthodes ont besoin du même nom pour que la propriété fonctionne. Si vous définissez le setter avec un nom différent comme celui-ci, cela ne fonctionnera pas :
Et une autre chose qui n'est pas complètement facile à repérer au début, c'est l'ordre: le getter doit être défini en premier . Si vous définissez d'abord le setter, vous obtenez une
name 'x' is not defined
erreur.la source
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. Nommer les méthodes comme suit entraînera une exception:
Donnez plutôt le même nom aux deux méthodes
Il est également important de noter que l'ordre de la déclaration compte. Le getter doit être défini avant le setter dans le fichier sinon vous obtiendrez un
NameError: name 'x' is not defined
la source
NameError: name 'x' is not defined
exception.Vous devez utiliser des classes de style nouveau, ce que vous faites en dérivant votre classe de object:
Ensuite, cela devrait fonctionner.
la source
Dans le cas où quelqu'un vient ici de Google, en plus des réponses ci-dessus, je voudrais ajouter que cela nécessite une attention particulière lors de l'appel du setter à partir de la
__init__
méthode de votre classe basée sur cette réponse Plus précisément:la source
__init__
méthode, mais de toute autre méthode de la classe.