【问题标题】:Descriptors : Precendence of Attribute access through __getattribute()__描述符:通过 __getattribute__ 访问属性的优先级
【发布时间】:2012-09-27 10:50:54
【问题描述】:

__getattribute__() 特殊方法和Descriptors 的上下文中,我无法理解以下优先级是什么意思

我在Core Python Programming 中的topic("Precedence") - under topic ("Desriptors") 下读了 3 遍,仍然无法通过它。谁能解释这些优先级是什么,它们的用途是什么??

  • 类属性
  • 数据描述符
  • 实例属性
  • 非数据描述符
  • 默认为__getattr__()

我还阅读了python documentation,在那里我找到了以下声明:-

对于实例绑定,描述符调用的优先级取决于 关于定义了哪些描述符方法。描述符可以定义 __get__()__set__()__delete__() 的任意组合。如果确实如此 未定义__get__(),则访问该属性将返回 描述符对象本身,除非对象的 实例字典。如果描述符定义了__set__() 和/或 __delete__(),是数据描述符;如果两者都没有定义,则它是非数据描述符。通常,数据描述符同时定义__get__()__set__(),而非数据描述符只有__get__() 方法。

定义了**__set__()****__get__()** 的数据描述符始终覆盖 实例字典中的重新定义。相反,非数据 描述符可以被实例覆盖。

Python 方法(包括staticmethod()classmethod())是 实现为非数据描述符。因此,实例可以 重新定义和覆盖方法。这允许单个实例 获得与同一类的其他实例不同的行为。

谁能举一个小例子来解释first paragraph 是什么意思? 还有这句话是什么意思-override a redefinition in an instance dictionary??

【问题讨论】:

标签: python python-2.7


【解决方案1】:

假设你有一个班级:

class C(object):
    dd = MyDataDescriptor()
    ndd = MyNonDataDescriptor()
    def __init__(self):
        self.__value = 1

让我们首先看一下数据描述符。如果在你的代码中你这样做:

cobj = C()
cobj.dd

根据上述段落,cobj.__dict__ 对象在访问dd 属性时将始终覆盖,即始终使用描述符对象的__get__/__set__/__del__ 方法而不是字典。唯一的例外发生在描述符对象没有定义__get__ 方法时。然后,如果cobj.__dict__ 对象中有dd 键,则将读取其值,否则将返回描述符对象本身。

现在是非数据描述符。如果在您的代码中调用:

cobj.ndd = 2

然后cobj.__dict__隐藏非数据描述符和ndd属性总是从cobj.__dict__对象中读取。所以如果你这样做:

cobj.ndd

不会调用描述符的__get__ 方法。但是如果你从字典中删除属性:

del cobj.ndd

然后描述符又回来了,所以调用

cobj.ndd

将调用描述符上的__get__ 方法。

【讨论】:

  • 非常感谢 Vicent,为您提供了如此精彩而详尽的解释。我现在所有的疑问都清楚了。再次感谢您 :)
猜你喜欢
  • 2015-08-01
  • 2019-01-26
  • 2014-05-02
  • 1970-01-01
  • 2015-08-29
  • 1970-01-01
  • 2014-09-11
  • 1970-01-01
  • 2012-05-26
相关资源
最近更新 更多