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()
andclassmethod()
) 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, i.e.__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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With