All Ihr Code tut, abgesehen von den Wert zu negieren, rufen Sie die Elternklasse __setattr__
, die genau das ist, was ohne Ihre __setattr__
Methode passieren würde. Die kurze Antwort lautet also: Sicher kannst du eine __setattr__
definieren.
Was Sie nicht tun können, ist __setattr__
neu definieren self.__dict__
zu verwenden, da Instanzen einer Klasse mit Schlitzen nicht haben ein __dict__
Attribut. Aber solche Instanzen tun haben ein self.x
Attribut, es ist Inhalt nicht nur in einem Wörterbuch auf der Instanz gespeichert.
Stattdessen werden die Slot-Werte an der gleichen Stelle gespeichert, andernfalls würde ein Instanz-Wörterbuch gespeichert werden. auf dem Objektheap. Platz ist reserviert für len(__slots__)
Referenzen, und descriptors auf den Klassenzugriff diese Referenzen in Ihrem Namen.
Also, in einem __setattr__
Haken, können Sie einfach direkt stattdessen jene Deskriptoren nennen:
def __setattr__(self, key, value):
if key == 'x':
Foo.__dict__[key].__set__(self, -value)
Interessante Umweg: ja, Klassen ohne __slots__
Attribut gibt ist ein Schlagwort, dass Sie Zugriff geben würde, zum __dict__
Objekt der Instanzen:
>>> class Bar(object): pass
...
>>> Bar.__dict__['__dict__']
<attribute '__dict__' of 'Bar' objects>
>>> Bar.__dict__['__dict__'].__get__(Bar(), Bar)
{}
die ist, wie normale Instanzen aussehen kann bis self.__dict__
. Was Sie fragt, wo das Bar.__dict__
Objekt gefunden wird. In Python ist es turtles all the way down, Sie aussehen würde, die auf dem type
Objekt natürlich Objekt bis:
>>> type.__dict__['__dict__']
<attribute '__dict__' of 'type' objects>
>>> type.__dict__['__dict__'].__get__(Bar, type)
dict_proxy({'__dict__': <attribute '__dict__' of 'Bar' objects>, '__module__': '__main__', '__weakref__': <attribute '__weakref__' of 'Bar' objects>, '__doc__': None})
tut hier __dict__ zu arbeiten? ist das, weil die effektive Adresse von __dict__ und die Heap-Elemente die gleiche ist, und das ist eine Art Osterei? oder meinst du __slots__? –
@CorleyBrigman: Verwechseln Sie nicht das "__dict__" der ** Klasse ** mit dem der ** Instanz **. Instanzen der Klasse "Foo" haben kein Attribut "__dict__". –
@CorleyBrigman: Und 'Foo'-Instanzen haben kein '__dict__'-Attribut, weil' Foo .__ dict __ ['__ dict __']' einen 'KeyError' auslöst. –