描述符:通过__getattribute()__对属性访问的优先级

Roh*_*ain 7 python python-2.7

我无法理解以下优先级在__getattribute__()特殊方法和特定方法的上下文中意味着什么Descriptors

我下读这topic("Precedence") - under topic ("Desriptors")从本书的核心Python编程 3次,仍不能获得通过它..任何一个可以解释一下这些优先级,在那里它们被用于??

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

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

对于实例绑定,描述符调用的优先级取决于定义的描述符方法.描述符可以定义的任何组合__get__(),__set__()__delete__().如果它没有定义__get__(),那么访问该属性将返回描述符对象本身,除非对象的实例字典中有值.如果描述符定义__set__()和/或 __delete__(),则它是数据描述符; 如果它既不定义,则它是非数据描述符.通常情况下,数据描述符同时定义__get__()__set__(),非数据描述符刚才的__get__() 方法.

带有**__set__()****__get__()**定义的数据描述符总是覆盖实例字典中的重定义.相反,非数据描述符可以被实例覆盖.

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

任何人都可以举一个小例子来解释first paragraph它的全部意义吗?这又是什么意思 - override a redefinition in an instance dictionary??

Vic*_*ent 4

假设你有一堂课:

class C(object):
    dd = MyDataDescriptor()
    ndd = MyNonDataDescriptor()
    def __init__(self):
        self.__value = 1
Run Code Online (Sandbox Code Playgroud)

让我们首先看一下数据描述符。如果您在代码中执行以下操作:

cobj = C()
cobj.dd
Run Code Online (Sandbox Code Playgroud)

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

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

cobj.ndd = 2
Run Code Online (Sandbox Code Playgroud)

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

cobj.ndd
Run Code Online (Sandbox Code Playgroud)

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

del cobj.ndd
Run Code Online (Sandbox Code Playgroud)

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

cobj.ndd
Run Code Online (Sandbox Code Playgroud)

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