Доступ к атрибутам в Python: сначала слоты, затем дикт?
В приведенном ниже примере атрибут 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__()
всегда переопределяют переопределение в словаре экземпляров. Напротив, неданные дескрипторы могут быть переопределены экземпляры.И с той же страницы, раздел о слотах :
__slots__
реализуются на уровне класса путем создания дескрипторов (реализующих дескрипторы) для каждого имени переменной. В результате атрибуты класса не могут использоваться для задания значений по умолчанию для переменных, определенных в__slots__
; в противном случае атрибут класса перезапишет назначение дескриптора.