描述符:通过__getattribute__进行属性访问的优先级

时间:2012-09-27 10:50:54

标签: python python-2.7

我无法理解以下优先级在__getattribute__()特殊方法和Descriptors

的上下文中的含义

我在书籍Core Python Programmingtopic("Precedence") - under topic ("Desriptors")下阅读了3次,仍然无法解决这个问题。任何人都可以解释这些优先级是什么,以及它们用于何处?< / p>

  • 类属性
  • 数据描述符
  • 实例属性
  • 非数据描述符
  • 默认为__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 ??

是什么意思

1 个答案:

答案 0 :(得分:4)

假设您有一个班级:

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

让我们先看看数据描述符。如果您在代码中执行:

cobj = C()
cobj.dd

相应于上一段,当访问cobj.__dict__属性时,dd对象将始终覆盖,即描述符对象的__get__/__set__/__del__方法将总是用来代替字典。当描述符对象未定义__get__方法时,会发生唯一的异常。然后,如果dd对象中存在cobj.__dict__键,则将读取其值,否则将返回描述符对象本身。

现在为非数据描述符。如果您在代码中致电:

cobj.ndd = 2

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

cobj.ndd

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

del cobj.ndd

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

cobj.ndd

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