2013-02-28 10 views
6

Im Beispiel unten, Attribut x wird auch aus den Schlitzen des Objekts zugegriffen obwohl x in __dict__ vorhanden ist (dies ist nicht ein typischer oder wahrscheinlich nützlich Fall ist, aber ich bin neugierig):Attribut Zugriff in Python: erste Slots, dann __dict__?

>>> class C(object): 
...  __slots__ = 'x' 
...  
>>> class D(C): 
...  pass 
... 
>>> obj = D() 
>>> obj.x = 'Stored in slots' 
>>> obj.__dict__ 
{} 
>>> obj.__dict__['x'] = 'stored in __dict__' 
>>> obj.x 
'Stored in slots' 

Ist diese Reihenfolge des Zugriffs (Slots zuerst) ein dokumentiertes Verhalten? oder einfach ein Implementierungsdetail?

Antwort

10

Ja, die eines Objekts wird nur konsultiert, nachdem die Datendeskriptoren konsultiert wurden. __slots__ Attribute sind als Datendeskriptoren implementiert.

Siehe Invoking descriptors:

Zum Beispiel Bindungen Aufruf der Vorrang des Descriptor auf der dem Descriptor hängt Methoden definiert sind. Ein Deskriptor kann eine beliebige Kombination von __get__(), __set__() und __delete__() definieren. Wenn __get__() nicht definiert wird, gibt der Zugriff auf das Attribut das Deskriptorobjekt selbst zurück, es sei denn, es gibt einen Wert im Instanzwörterbuch des Objekts. Wenn der Deskriptor __set__() und/oder __delete__() definiert, handelt es sich um einen Datendeskriptor; Wenn es keine definiert, ist es ein Nicht-Datendeskriptor. Normalerweise definieren Datendeskriptoren sowohl __get__() als auch __set__(), während Nicht-Datendeskriptoren nur die __get__()-Methode haben. Datendekriptoren mit __set__() und __get__() definiert überschreiben immer eine Neudefinition in einem Instanzwörterbuch. Im Gegensatz dazu können Nicht-Datendeskriptoren von Instanzen überschrieben werden.

und von der gleichen Seite, section on slots:

__slots__ sind auf der Klassenebene realisiert durch Deskriptoren (Implementing Descriptors) für jeden Variablennamen zu schaffen. Daher können Klassenattribute nicht zum Festlegen von Standardwerten für Instanzvariablen verwendet werden, die durch __slots__ definiert sind. Andernfalls würde das Klassenattribut die Deskriptorzuweisung überschreiben.

+0

Ich glaube, das sollte auch zitiert werden (aus [Implementierende Deskriptoren] (http://docs.python.org/2/reference/datamodel.html#implementing-descriptors)): "Der Deskriptor muss in beiden sein das Klassenwörterbuch des Eigentümers oder im Klassenwörterbuch für eines seiner Eltern ". –

+1

@PavelAnossov: Nicht sicher, was das zum Verständnis von Steckplätzen beitragen würde. Die Slot-Attribute werden als Deskriptoren für die Klasse implementiert, und Datendeskriptoren kommen vor den Werten der Instanz "__dict__". Das ist genug, um dieses Verhalten zu dokumentieren, nicht wahr? –

+0

@PavelAnossov: Ja, manchmal sind die Leute verwirrt, wo Deskriptoren nachgeschlagen werden, aber das steht hier nicht in Frage. –