2013-02-28 4 views
6

В приведенном ниже примере, атрибут x доступен из слотов объекта, даже если x присутствует в __dict__ (это не является типичным или, возможно, полезно бывает, но мне интересно):Доступ к атрибутам в Python: первые слоты, затем __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 этот порядок доступа (сначала слоты) документированное поведение? или просто деталь реализации?

ответ

10

Да, __dict__ объекта рассматривается только после того, как были обработаны дескрипторы данных. Атрибуты __slots__ реализованы как дескрипторы данных.

Invoking descriptors См:

, например, привязки, то приоритет дескриптора вызова зависит от того, какие методы дескриптора определены. Дескриптор может определять любую комбинацию из __get__(), __set__() и __delete__(). Если он не определяет __get__(), тогда доступ к атрибуту будет возвращать сам объект дескриптора, если в словаре экземпляра объекта нет значения. Если дескриптор определяет __set__() и/или __delete__(), это дескриптор данных; если он не определяет ни одного, это дескриптор без данных. Обычно дескрипторы данных определяют как __get__(), так и __set__(), в то время как дескрипторы без данных имеют только метод __get__(). Дескрипторы данных с __set__() и __get__(), определенными всегда, переопределяют переопределение в словаре экземпляра. Напротив, дескрипторы данных без данных могут быть переопределены экземплярами.

и с той же страницы, section on slots:

__slots__ реализуются на уровне класса путем создания дескрипторов (Реализация ДЕСКРИПТОРОВ) для каждого имени переменной. В результате атрибуты класса не могут использоваться для установки значений по умолчанию для переменных экземпляра, определяемых __slots__; в противном случае атрибут класса будет перезаписывать назначение дескриптора.

+0

Я считаю, что это также следует указывать (из [Реализация дескрипторов] (http://docs.python.org/2/reference/datamodel.html#implementing-descriptors)): «дескриптор должен быть в любом словарь класса владельца или словарь классов для одного из его родителей ». –

+1

@PavelAnossov: Не уверен, что это добавит к пониманию слотов. Атрибуты слота реализованы как дескрипторы класса, а дескрипторы данных - до значений '__dict__'. Этого достаточно, чтобы документировать это поведение, не так ли? –

+0

@PavelAnossov: Да, иногда люди путаются относительно того, где ищут дескрипторы, но это не проблема. –

Смежные вопросы