Доступ к атрибутам в Python: сначала слоты, затем dict?

в приведенном ниже примере атрибут x доступ из слотов объекта, даже если x присутствует __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'

является ли этот порядок доступа (сначала слоты) документированным поведением? или просто деталь реализации?

1 ответов


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

посмотреть вызов дескрипторов:

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

и с той же страницы, слоты:

__slots__ реализуются на уровне класса путем создания дескрипторов (реализующих дескрипторы) для каждого имени переменной. В результате атрибуты класса не могут использоваться для установки значений по умолчанию для переменных экземпляра, определенных __slots__; в противном случае атрибут class перезапишет назначение дескриптора.