В этой статье описывается, как Python ищет атрибут объекта при его выполнении o.a
.Порядок приоритетов интересен - он ищет:
- Атрибут класса, который является дескриптором данных (чаще всего это свойство)
- Атрибут экземпляра
- Любойдругой атрибут класса
Мы можем подтвердить это с помощью приведенного ниже кода, который создает объект o
с атрибутом экземпляра a
, класс которого содержит свойство с тем же именем:
class C:
def __init__(self):
self.__dict__['a'] = 1
@property
def a(self):
return 2
o = C()
print(o.a) # Prints 2
Почему Python использует этот порядок приоритетов, а не «наивный» порядок (атрибуты экземпляра имеют приоритет над всеми атрибутами класса)?Порядок приоритетов в Python имеет существенный недостаток: он замедляет поиск атрибутов, потому что вместо простого возврата атрибута o
, если он существует (общий случай), Python должен сначала найти класс o
и все егосуперклассы для дескриптора данных.
В чем преимущество порядка приоритетов Python?Предположительно, это не только для описанной выше ситуации, потому что наличие переменной экземпляра и свойства с одинаковым именем является очень угловым случаем (обратите внимание на необходимость использования self.__dict__['a'] = 1
для создания атрибута экземпляра, потому что обычный self.a = 1
вызоветсвойство).
Существует ли другая ситуация, в которой "наивный" порядок поиска может вызвать проблемы?