Warum funktioniert @ foo.setter in Python nicht für mich?

Also, ich spiele mit Dekorateuren in Python 2.6, und ich habe einige Mühe, sie zu arbeiten. 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 

Was ich dachte, das bedeutet, x wie eine Eigenschaft zu behandeln, aber nennen diese Funktionen auf get und set. Also habe ich IDLE gefeuert und es überprüft:

 >>> from testDec import testDec from testDec import testDec >>> t = testDec() t = testDec() >>> tx tx 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' >>> tx = 5 tx = 5 >>> tx tx 5 

Offensichtlich funktioniert der erste Aufruf wie erwartet, da ich den Getter anrufe, und es gibt keinen Standardwert, und es scheitert. OK, gut, ich verstehe Allerdings scheint der Aufruf, tx = 5 zuzuweisen, eine neue Eigenschaft x zu erstellen, und nun funktioniert der Getter nicht!

Was vermisse ich?

  • Python-Dekorator automatisch definieren __init__ Variablen
  • Wie kann ich eine Klasseninstanzvariable als Argument für einen Methodendekorator in Python verwenden?
  • In Python, schmücken zwei Methoden mit dem gleichen Namen, um sie zu unterscheiden
  • Java: automatische Memoisierung
  • Wie man eine Klasse automatisch registriert, wenn sie definiert ist
  • Python, verwirrt in dekorieren und schließen
  • 4 Solutions collect form web for “Warum funktioniert @ foo.setter in Python nicht für mich?”

    Sie scheinen klassische Old-Class-Klassen zu verwenden . Damit die Eigenschaften korrekt funktionieren, müssen Sie stattdessen neuartigen Klassen verwenden ( vom object erben ). Kennen Sie einfach Ihre Klasse als 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 

    Es klappt:

     >>> k = testDec() >>> kx 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' >>> kx = 5 called setter >>> kx called getter 5 >>> 

    Nur eine Notiz für andere Leute, die hier stolpern auf der Suche nach dieser Ausnahme: beide Funktionen müssen den gleichen Namen haben. Das Benennen der Methoden wie folgt führt zu einer Ausnahme:

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

    Stattdessen geben beide Methoden den gleichen Namen

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

    Du musst neuartige Klassen verwenden, die du tust, indem du deine Klasse aus dem Objekt abgibst:

     class testDec(object): .... 

    Dann sollte es funktionieren

    Für den Fall, dass jemand hier von Google kommt, zusätzlich zu den oben genannten Antworten möchte ich hinzufügen, dass dies braucht sorgfältige Aufmerksamkeit beim Aufrufen der Setter aus der __init__ Methode Ihrer Klasse auf der Grundlage dieser Antwort Speziell:

     class testDec(object): def __init__(self, value): print 'We are in __init__' self.x = value # Will call the setter. Note just x here #self._x = value # Will not call the setter @property def x(self): print 'called getter' return self._x # Note the _x here @x.setter def x(self, value): print 'called setter' self._x = value # Note the _x here t = testDec(17) print tx Output: We are in __init__ called setter called getter 17 
    Python ist die beste Programmiersprache der Welt.