Почему объекты дескриптора python не работают при назначении классу в __init__?

Я знаю, как работают дескрипторы в Python, по крайней мере, до сегодняшнего дня.

Если член класса определяет __set__(), это дескриптор данных, а foo.member вернет foo.member.__get__(foo.member, foo) вместо объекта foo.member. Но это работает только в том случае, если foo.member определено в теле класса, а не назначено после создания класса.

Например, этот код возвращает объект дескриптора:

In [1]:  class descr(object):
   ...:         def __get__(self, obj, type=None):
   ...:                 return obj
   ...:         def __set__(self, obj, val):
   ...:                 print('Setting', val, 'to', obj)
   ...:         

In [2]: class C:
   ...:     pass
   ...: 

In [3]: c=C()

In [4]: c.foo=descr()

In [5]: c.foo
Out[5]: <__main__.descr at 0x7fd6450bc4e0>

In [6]: c.foo =5

In [7]: c.foo
Out[7]: 5

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

In [1]: class descr(object):
    def __get__(self, obj, type=None):
        return obj
    def __set__(self, obj, val):
        print('Setting', val, 'to', obj)
   ...:         

In [2]: class C(object):
    descr=descr()
   ...:     

In [4]: c=C()

In [5]: c.descr
Out[5]: <__main__.C at 0x7fb75011fa50>

In [6]: c.descr=5
('Setting', 5, 'to', <__main__.C object at 0x7fb75011fa50>)

Кто-нибудь может подробно рассказать об этом?


person Ojomio    schedule 07.12.2016    source источник
comment
Вы не назначаете его классу, c в этом случае является экземпляром. Дескрипторы работают на уровне класса.   -  person Ashwini Chaudhary    schedule 07.12.2016
comment
Также: stackoverflow.com/questions/1004168/ stackoverflow.com/questions/12599972/   -  person mata    schedule 07.12.2016