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??

  • Class attributes
  • Data descriptors
  • Instance attributes
  • Non-data descriptors
  • Defaulting to __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.

    链接地址: http://www.djcxy.com/p/64236.html

    上一篇: tcl执行结果重定向到stdout也需要被存储

    下一篇: 描述符:通过属性访问的优先级