python数据和非数据描述符

标签 python descriptor python-descriptors

根据 Python's documentation ,

Data descriptors with __set__() and __get__() defined always override a redefinition in an instance dictionary.

我对这句话的理解没问题,但是有人能帮我解释一下为什么会有这样的规则吗?毕竟,如果我想覆盖实例字典中的属性,我已经需要明确地(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'

如您所见,即使我在实例 __dict__ 中添加了一个 spam 条目,它也被完全忽略并且 Foo.spam属性(property)仍在使用。 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>

关于python数据和非数据描述符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13007179/

相关文章:

python - 使用 getattr 获取包含在描述符中的方法

Python 描述符 __get__ 和 __set__

python - 对非类属性使用 Python 的 __get__ 描述符

python - 如何在Python中实现描述符

python - 使用 Python 进行快速排序

json - 如何仅使用消息描述符将 protobuf 线格式转换为 JSON?

python - python 中的条件日志记录

python - 可选参数和描述符实例

python - Matlab 谱图和 matplotlib 谱图之间的区别?

python - 使用 Mechanize 获取证书验证失败错误