Ich spiele also mit Dekorateuren in Python 2.6 und habe Probleme, sie zum Laufen zu bringen. Hier ist meine Klassendatei:
class testDec:
@property
def x(self):
print 'called getter'
return self._x
@x.setter
def x(self, value):
print 'called setter'
self._x = value
Ich dachte, dies würde bedeuten, x
wie eine Eigenschaft zu behandeln , aber diese Funktionen beim Abrufen und Festlegen aufzurufen. Also habe ich IDLE gestartet und es überprüft:
>>> 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
Offensichtlich funktioniert der erste Aufruf wie erwartet, da ich den Getter aufrufe und es keinen Standardwert gibt und er fehlschlägt. OK, gut, ich verstehe. Der Aufruf zum Zuweisen t.x = 5
scheint jedoch eine neue Eigenschaft zu erstellen x
, und jetzt funktioniert der Getter nicht mehr!
Was vermisse ich?
Antworten:
Sie scheinen in Python 2 klassische Klassen alten Stils zu verwenden . Damit Eigenschaften ordnungsgemäß funktionieren, müssen Sie stattdessen Klassen neuen Stils verwenden (in Python 2 müssen Sie von erben
object
). Erklären Sie einfach Ihre Klasse alsMyClass(object)
:Es klappt:
Ein weiteres Detail, das Probleme verursachen kann, besteht darin, dass beide Methoden denselben Namen benötigen, damit die Eigenschaft funktioniert. Wenn Sie den Setter mit einem anderen Namen wie diesem definieren, funktioniert dies nicht :
Und eine weitere Sache, die zunächst nicht ganz leicht zu erkennen ist, ist die Reihenfolge: Der Getter muss zuerst definiert werden . Wenn Sie zuerst den Setter definieren, wird eine
name 'x' is not defined
Fehlermeldung angezeigt.quelle
Nur ein Hinweis für andere Leute, die hier auf der Suche nach dieser Ausnahme stolpern: Beide Funktionen müssen denselben Namen haben. Wenn Sie die Methoden wie folgt benennen, führt dies zu einer Ausnahme:
Geben Sie stattdessen beiden Methoden den gleichen Namen
Es ist auch wichtig zu beachten, dass die Reihenfolge der Erklärung von Bedeutung ist. Der Getter muss vor dem Setter in der Datei definiert werden, sonst erhalten Sie einen
NameError: name 'x' is not defined
quelle
NameError: name 'x' is not defined
Ausnahme erhalten.Sie müssen Klassen neuen Stils verwenden, indem Sie Ihre Klasse vom Objekt ableiten:
Dann sollte es funktionieren.
quelle
Für den Fall, dass jemand von Google hierher kommt, möchte ich zusätzlich zu den obigen Antworten hinzufügen, dass dies besondere Aufmerksamkeit erfordert, wenn Sie den Setter aus der
__init__
Methode Ihrer Klasse aufrufen, die auf dieser Antwort basiert. Speziell:quelle
__init__
Methode, sondern von jeder anderen Methode in der Klasse.