Недавно я прочитал официальный HOW-TO по дескрипторам Python, который фактически взят из эссе, написанное Рэймондом Хеттингером давным-давно. Но прочитав его несколько раз, я все еще не понимаю некоторые его части. Я процитирую несколько абзацев, а затем мои недоумения и вопросы.
Если в словаре экземпляра есть запись с тем же именем, что и у дескриптора данных, дескриптор данных имеет приоритет. Если в словаре экземпляра есть запись с тем же именем, что и у дескриптора, не относящегося к данным, то запись словаря имеет приоритет.
- То же самое и с классом? Какова цепочка приоритетов класса, если в его словаре есть запись с тем же именем, что и у дескриптора данных/не данных?
Для объектов механизм находится в
object.__getattribute__()
, который преобразуетb.x
вtype(b).__dict__['x'].__get__(b, type(b))
. Реализация работает через цепочку приоритетов, которая дает дескрипторам данных приоритет над переменными экземпляра, приоритет переменных экземпляра над дескрипторами, не относящимися к данным, и присваивает самый низкий приоритет__getattr__()
, если он предоставлен.Для классов механизм находится в
type.__getattribute__()
, который преобразуетB.x
вB.__dict__['x'].__get__(None, B)
.
- The above two paragraphs tell the process of a descriptor's being invoked automatically upon attribute access. It lists the difference between attribute's being accessed by an instance (
b.x
) and a class (B.x
). However, here are my confusions:- if the attribute of a class or an instance is not a descriptor, will the transformation (i.e., transforms
b.x
intotype(b).__dict__['x'].__get__(b, type(b))
andB.x
intoB.__dict__['x'].__get__(None, B)
) still proceed? Is returning the attribute in this class's or instance's dict directly simpler? - Если в словаре экземпляра есть запись с тем же именем, что и у дескриптора, не относящегося к данным, в соответствии с правилом приоритета в первой цитате, запись словаря имеет приоритет, будет ли в это время продолжаться преобразование? Или просто вернуть значение в его dict?
- if the attribute of a class or an instance is not a descriptor, will the transformation (i.e., transforms
Дескрипторы, не относящиеся к данным, обеспечивают простой механизм для вариаций обычных шаблонов связывания функций в методы.
- Выбраны ли дескрипторы, не относящиеся к данным, потому что функции/методы можно только получить, но нельзя установить?
- Каков основной механизм привязки функций к методам? Поскольку словари классов хранят методы как функции, если мы вызываем один и тот же метод, используя класс и его экземпляр соответственно, как базовая функция может определить, должен ли ее первый аргумент быть self или нет?
Функции имеют метод
__get__()
, поэтому их можно преобразовать в метод при доступе к ним как к атрибутам. Дескриптор без данных преобразует вызовobj.f(*args)
вf(obj, *args)
. Вызовklass.f(*args)
становится f(*args).
- Как дескриптор без данных может преобразовать вызов
obj.f(*args)
вf(obj, *args)
? - Как дескриптор без данных может преобразовать вызов
klass.f(*args)
вf(*args)
? - Каков основной механизм двух вышеупомянутых преобразований? Почему существуют различия между классом и экземпляром?
- Какую роль играет метод
__get__()
в вышеуказанных обстоятельствах?