2015-04-28 3 views
2

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

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

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

Согласно Python documentation:

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 
+0

Я не совсем понимаю, в чем проблема? – user3467349

+0

@ user3467349: 'm.z' и' m.x' - оба экземпляра класса 'RevealAccess', который реализует протокол дескриптора. OP ожидал, что протокол будет использоваться как для 'm.z', так и для' m.x'. –

+0

@ пользователь3467349: например. вам нужно понять, что протокол дескриптора * есть *, прежде чем вы сможете ответить на вопрос. –

ответ

5

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

От Descriptor HOWTO:

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

и в Implementing Descriptors section модели данных Python:

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

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