Descriptors : Precendence of Attribute access through
 I can't understand what does the below precedence means in context of __getattribute__() special method and Descriptors  
 I read this under the topic("Precedence") - under topic ("Desriptors") from book Core Python Programming 3 times, still can't get through it.. Can any one explain what are these precedence, and where they are used for??  
__getattr__()  I also read the python documentation, where I found the below statement: -
 For instance bindings, the precedence of descriptor invocation depends on the which descriptor methods are defined.  A descriptor can define any combination of __get__() , __set__() and __delete__() .  If it does not define __get__() , then accessing the attribute will return the descriptor object itself unless there is a value in the object's instance dictionary.  If the descriptor defines __set__() and/or __delete__() , it is a data descriptor;  if it defines neither, it is a non-data descriptor.  Normally, data descriptors define both __get__() and __set__() , while non-data descriptors have just the __get__() method.  
 Data descriptors with **__set__()** and **__get__()** defined always override a redefinition in an instance dictionary.  In contrast, non-data descriptors can be overridden by instances.  
 Python methods (including staticmethod() and classmethod() ) are implemented as non-data descriptors.  Accordingly, instances can redefine and override methods.  This allows individual instances to acquire behaviors that differ from other instances of the same class.  
 Can anyone give a small example to explain what the first paragraph is all about?  Also what does it mean by saying - override a redefinition in an instance dictionary ??  
Suppose you have a class:
class C(object):
    dd = MyDataDescriptor()
    ndd = MyNonDataDescriptor()
    def __init__(self):
        self.__value = 1
Let's look first at data descriptors. If in your code you do:
cobj = C()
cobj.dd
 accordingly to the above paragraph, the cobj.__dict__ object will be always overriden when the dd attribute is accessed, ie __get__/__set__/__del__ methods of the descriptor object will always be used instead of the dictionary.  The only exception occurs when the descriptor object doesn't define a __get__ method.  Then if there is a dd key in the cobj.__dict__ object its value will be read, if not the descriptor object itself will be returned.  
Now for the non-data descriptors. If in your code you call:
cobj.ndd = 2
 then the cobj.__dict__ hides the non-data descriptor and the ndd attribute is always read from the cobj.__dict__ object.  So if you do:  
cobj.ndd
 the __get__ method of the descriptor will not be called.  But if you delete the attribute from the dictionary:  
del cobj.ndd
then the descriptor is back, so calling
cobj.ndd
 will call the __get__ method on the descriptor.  
下一篇: 描述符:通过属性访问的优先级
