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.
下一篇: 描述符:通过属性访问的优先级