Понимание дескрипторов Python

Я пытаюсь лучше понять дескрипторы.

Я не понимаю, почему в методе foo дескрипторы __get__ метод не вызывается.

Насколько я понимаю, дескрипторы __get__ метод всегда вызывается, когда я получаю доступ к атрибуту объектов через оператор точки или когда я использую __getattribute__(),

Согласно документации Python:

class RevealAccess(object):
    def __init__(self, initval=None, name='var'):
        self.val = initval
        self.name = name

    def __get__(self, obj, objtype):
        print('Retrieving', self.name)
        return self.val

    def __set__(self, obj, val):
        print('Updating', self.name)
        self.val = val

class MyClass(object):
    x = RevealAccess(10, 'var "x"')
    y = 5

    def foo(self):
        self.z = RevealAccess(13, 'var "z"')
        self.__getattribute__('z')
        print(self.z)

m = MyClass()
m.foo()
m.z # no print
m.x # prints var x

1 ответ

Решение

z является атрибутом экземпляра, а не класса. Протокол дескриптора применяется только к атрибутам, полученным из класса.

Из дескриптора HOWTO:

Для объектов, оборудование находится в object.__getattribute__() который превращает b.x в type(b).__dict__['x'].__get__(b, type(b)),

и в разделе " Реализация дескрипторов " модели данных Python:

Следующие методы применяются только тогда, когда экземпляр класса, содержащий метод (так называемый класс дескриптора), появляется в классе владельца (дескриптор должен находиться либо в словаре классов владельца, либо в словаре классов для одного из его родителей).

Ваш m.z не может быть найдено в классе dict; type(m).__dict__['z'] не существует; это найдено в m.__dict__['z'] вместо. Вот m это экземпляр, а класс владельца MyClass, а также z не появляется в словаре класса владельца.

Другие вопросы по тегам