2012-09-27 32 views
7

我不明白什么是以下优先意味着__getattribute__()特殊的方法和Descriptors描述符:属性访问Precendence通过__getattribute()__

的情况下,我从书插在topic("Precedence") - under topic ("Desriptors")阅读本Core Python Programming 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 ??

+0

相关:[?哪个Python语言规则允许该描述符将被首先发现(http://stackoverflow.com/questions/1865902/),[描述符和python提供的属性(http://stackoverflow.com /问题/ 10536539 /) –

+0

@PiotrDobrogost ..感谢彼得·对于那些链接.. :) –

回答

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__方法时发生唯一的例外。然后,如果在cobj.__dict__对象dd关键它的值将被读取,如果没有描述符对象本身将被退回。

现在对于非数据描述符。如果在你的代码中调用:

cobj.ndd = 2 

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

cobj.ndd 

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

del cobj.ndd 

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

cobj.ndd 

将呼吁描述符__get__方法。

+0

谢谢你洙多维森特,对于这样一个很好的和精细的解释。我所有的疑虑现在清楚..再次谢谢:) –