ant*_*ony 11 python descriptor python-descriptors
根据Python的文档,
带有
__set__()和__get__()定义的数据描述符总是覆盖实例字典中的重定义.
我理解这句话没有问题,但是有人可以为我澄清为什么会有这样的规则吗?毕竟,如果我想覆盖实例字典中的属性,我已经需要明确地执行(inst.__dict__["attr"] = val),因为天真inst.attr = val会调用描述符的__set__方法,这通常会覆盖实例字典中的属性.
编辑:为了说清楚,我理解发生了什么,我的问题是为什么这样的规则到位.
覆盖适用于属于该类的 描述符__dict__.
Python将始终查找type(instance).__dict__[attributename].__get__(instance, type(instance)),不会用于instance.__dict__搜索实例覆盖.
下面是一个使用设计Descriptor类和属性的示例(它是一个带有a __get__和a 的描述符__set__:
>>> class Descriptor(object):
... def __init__(self, name):
... self.name = name
... def __get__(self, instance, cls):
... print 'Getting %s, with instance %r, class %r' % (self.name, instance, cls)
...
>>> class Foo(object):
... _spam = 'eggs'
... @property
... def spam(self):
... return self._spam
... @spam.setter
... def spam(self, val):
... self._spam = val
...
>>> Foo().spam
'eggs'
>>> foo = Foo()
>>> foo.__dict__['spam'] = Descriptor('Override')
>>> foo.spam
'eggs'
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,即使我spam在实例中添加了一个条目__dict__,它也会被完全忽略,并且Foo.spam仍会使用该属性.Python忽略了该实例,__dict__因为该spam属性定义了两者__get__和a __set__.
如果你使用一个没有定义__set__覆盖的描述符工作(但它__get__不被调用:
>>> class Foo(object):
... desc = Descriptor('Class-stored descriptor')
...
>>> Foo.desc
Getting Class-stored descriptor, with instance None, class <class '__main__.Foo'>
>>> Foo().desc
Getting Class-stored descriptor, with instance <__main__.Foo object at 0x1018df510>, class <class '__main__.Foo'>
>>> foo = Foo()
>>> foo.__dict__['desc'] = Descriptor('Instance-stored descriptor')
>>> foo.desc
<__main__.Descriptor object at 0x1018df1d0>
Run Code Online (Sandbox Code Playgroud)