Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Attribute access in Python: first slots, then __dict__?

In the example below, attribute x is accessed from the slots of the object even though x is present in __dict__ (this is not a typical or probably useful case, but I'm curious):

>>> 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 this order of access (slots first) a documented behavior? or simply an implementation detail?

like image 760
Eric O Lebigot Avatar asked Feb 28 '13 15:02

Eric O Lebigot


1 Answers

Yes, the __dict__ of an object is only consulted after data descriptors have been consulted. __slots__ attributes are implemented as data descriptors.

See Invoking descriptors:

For instance bindings, the precedence of descriptor invocation depends on the which descriptor methods are defined. A descriptor can define any combination of __get__(), __set__() and __delete__(). If it does not define __get__(), then accessing the attribute will return the descriptor object itself unless there is a value in the object’s instance dictionary. If the descriptor defines __set__() and/or __delete__(), it is a data descriptor; if it defines neither, it is a non-data descriptor. Normally, data descriptors define both __get__() and __set__(), while non-data descriptors have just the __get__() method. Data descriptors with __set__() and __get__() defined always override a redefinition in an instance dictionary. In contrast, non-data descriptors can be overridden by instances.

and from the same page, section on slots:

__slots__ are implemented at the class level by creating descriptors (Implementing Descriptors) for each variable name. As a result, class attributes cannot be used to set default values for instance variables defined by __slots__; otherwise, the class attribute would overwrite the descriptor assignment.

like image 173
Martijn Pieters Avatar answered Sep 27 '22 20:09

Martijn Pieters