2013-02-28 13 views
6

Nell'esempio che segue, attributo x si accede dalle fessure degli oggetti anche se x è presente in __dict__ (questo non è un caso tipico o probabilmente utile, ma sono curioso):Accesso agli attributi in Python: primi slot, quindi __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' 

Is questo ordine di accesso (slot prima) un comportamento documentato? o semplicemente un dettaglio di implementazione?

risposta

10

Sì, lo __dict__ di un oggetto viene consultato solo dopo aver consultato i descrittori di dati. Gli attributi __slots__ sono implementati come descrittori di dati.

Vedi Invoking descriptors:

per esempio attacchi, la precedenza di descrittore invocazione dipende quali metodi descrittori sono definiti. Un descrittore può definire qualsiasi combinazione di __get__(), __set__() e __delete__(). Se non definisce __get__(), l'accesso all'attributo restituirà l'oggetto descrittore stesso, a meno che non vi sia un valore nel dizionario di istanza dell'oggetto. Se il descrittore definisce __set__() e/o __delete__(), è un descrittore di dati; se non lo definisce, è un descrittore non dati. Normalmente, i descrittori di dati definiscono sia __get__() e __set__(), mentre i descrittori non di dati hanno solo il metodo __get__(). I descrittori di dati con __set__() e __get__() definiti sostituiscono sempre una ridefinizione in un dizionario di istanza. Al contrario, i descrittori non dati possono essere sovrascritti dalle istanze.

e dalla stessa pagina, section on slots:

__slots__ sono attuate a livello di classe creando descrittori (esecuzione Descrittori) per ciascuna variabile. Di conseguenza, non è possibile utilizzare gli attributi di classe per impostare valori predefiniti per variabili di istanza definite da __slots__; in caso contrario, l'attributo class sovrascrivere l'assegnazione del descrittore.

+0

Credo che questo dovrebbe anche essere citato (da [Implementing Descriptors] (http://docs.python.org/2/reference/datamodel.html#implementing-descriptors)): "il descrittore deve essere in entrambi il dizionario di classe del proprietario o nel dizionario di classe per uno dei suoi genitori ". –

+1

@PavelAnossov: non sono sicuro di cosa aggiungere alla comprensione degli slot. Gli attributi slot sono implementati come descrittori sulla classe, ei descrittori di dati vengono prima dei valori di istanza '__dict__'. Questo è sufficiente per documentare questo comportamento, non è vero? –

+0

@PavelAnossov: Sì, a volte le persone sono confuse su dove vengono visualizzati i descrittori, ma qui non è in discussione. –

Problemi correlati