根据Python的文档 ,
与数据描述符__set__()
和__get__()
总是被定义覆盖一个实例字典的重新定义。
我没有问题,理解了这句话,但有人可以澄清我为什么这样的规则是否到位? 毕竟,如果我想在一个实例字典重写的属性,我已经需要做的是明确地 ( inst.__dict__["attr"] = val
),作为一个天真inst.attr = val
会打电话描述符的__set__
方法,这将(通常)不能取代在实例字典的属性。
编辑:只是要清楚,我明白发生了什么,我的问题是,为什么这样的规则已经到位。
该覆盖适用于属于类的一部分描述__dict__
。
Python会始终查找type(instance).__dict__[attributename].__get__(instance, type(instance))
也不会用instance.__dict__
搜索一个实例覆盖。
下面是一个使用一个人为的一个例子Descriptor
的类和属性(其是具有描述符__get__
和__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'
正如你所看到的,即使我添加spam
的实例项__dict__
,它完全忽略, Foo.spam
属性是用来仍。 Python是忽略了实例__dict__
,因为spam
属性定义了__get__
和__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>