2013-04-19 3 views
7

Недавно я прочитал official HOW-TO about Python descriptors, который на самом деле происходит от an essay, написанного Раймондом Хеттингером давным-давно. Но, прочитав его несколько раз, я все еще смущен некоторыми его частями. Я приведу некоторые параграфы, за которыми следуют мои путаницы и вопросы.Заблуждения о дескрипторах Python и руководстве по описанию


Если словарь Экземпляр имеет запись с таким же именем, как дескриптор данных, дескриптор данных имеет приоритет. Если словарь экземпляра имеет запись с тем же именем, что и дескриптор не данных, запись словаря имеет приоритет.

  • Это то же самое с классом? Какова цепочка приоритетов для класса, если в его словаре есть запись с тем же именем, что и дескриптор данных/данных?

Для объектов, машины в object.__getattribute__(), который трансформирует b.x в type(b).__dict__['x'].__get__(b, type(b)). Реализация работает через цепочку приоритетов, которая дает приоритет дескрипторам данных над переменными экземпляра, приоритет переменных экземпляра над дескрипторами без данных и присваивает наименьший приоритет __getattr__(), если это предусмотрено.

Для классов оборудование находится в type.__getattribute__(), которое преобразует B.x в B.__dict__['x'].__get__(None, B).

  • Приведенных выше двух абзацев сказать процесс бытия дескриптора вызывается автоматически при доступе к атрибутам. В нем перечисляется разница между доступом к атрибуту экземпляра (b.x) и классом (B.x). Тем не менее, вот мои неурядицы:
    • если атрибут класса или экземпляр не дескриптор, будет преобразование (т.е. превращает b.x в type(b).__dict__['x'].__get__(b, type(b)) и B.x в B.__dict__['x'].__get__(None, B)) еще продолжается? Возвращает ли атрибут в этом классе или экземпляре dict непосредственно проще?
    • Если словарь экземпляра имеет запись с тем же именем, что и дескриптор без данных, в соответствии с правилом приоритета в первой цитате, запись словаря имеет приоритет, в это время будет продолжаться преобразование? Или просто верните значение в его dict?

дескрипторов Номера данных обеспечивает простой механизм для вариаций на обычных формах связывания функций в методы.

  • выбран дескрипторы без данных, поскольку функции/методы могут быть только получили, но не может быть установить?
  • В чем заключается механизм привязки функций к методам?Поскольку словари классов хранят методы как функции, если мы вызываем один и тот же метод с использованием класса и его экземпляра соответственно, как может основная функция определить, должен ли его первый аргумент 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__() в соответствии с вышеуказанным обстоятельством?

ответ

2

Это то же самое с классом? Какова цепочка приоритетов для класса, если в его словаре есть запись с тем же именем, что и дескриптор данных/данных?

Нет, если атрибут определен как в суперклассе, так и в подклассе, значение суперкласса полностью игнорируется.

если атрибут класса или экземпляр не дескриптор, будет преобразование (то есть, трансформирует Ьй в type(b).__dict__['x'].__get__(b, type(b)) и Bx в B.__dict__['x'].__get__(None, B)) еще продолжается?

Нет, он возвращает непосредственно объект получил от класса __dict__. Или что то же самое, да, если вы делаете вид, что все объекты имеют по умолчанию метода __get__(), который игнорирует аргументы и возвращает self.

Если словарь экземпляра имеет запись с тем же именем, что и дескриптор не данных, в соответствии с правилом приоритета в первой цитате, запись словаря имеет приоритет, в это время будет продолжаться преобразование? Или просто вернуть значение в своем dict?

Что не ясно в этом пункте, что вы цитируемого (может быть, это записано в другом месте), что, когда b.x решает вернуться b.__dict__['x'], не __get__ не вызывается в любом случае. __get__ вызывается точно, когда синтаксис b.x или B.x решает вернуть объект, который находится в классе dict.

Является ли дескрипторы без данных выбраны потому, что функции/методы могут быть получены только, но не могут быть установлены?

Да: они являются обобщением «старого стиля» модели класса в Python, в котором вы можете сказать B.f = 42 даже если f функция объекта, живущих в классе B. Это позволяет функциональный объект перекрываться с несвязанным объектом. Дескрипторы данных, с другой стороны, имеют разную логику для поддержки property.

В чем заключается механизм привязки функций к методам? Поскольку словари классов хранят методы как функции, если мы вызываем один и тот же метод с использованием класса и его экземпляра соответственно, как основная функция может определить, должен ли его первый аргумент быть самим собой или нет?

Чтобы понять это, вам нужно иметь «объекты метода». Синтаксис b.f(*args) эквивалентен (b.f)(*args), который представляет собой два этапа. Первый шаг вызывает f.__get__(b); это возвращает объект метода, который хранит как b, так и f. Второй шаг вызывает объект метода, который в свою очередь вызовет исходный f, добавив b в качестве дополнительного аргумента. Это то, что не происходит для B.f, просто потому, что B.f, то есть f.__get__(None, B), является просто f (в ​​Python 3). Это особый метод __get__ предназначен для объектов функций.

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

  • Нет связанных вопросов^_^