Descriptors: Superior Attribute Access via __getattribute () __

I can't figure out what the previous advantage means in the context of the special __getattribute__() method and Descriptors

I read this under topic("Precedence") - under topic ("Desriptors") from the Core Python Programming book 3 times, still can't get through this. Can anyone explain what these priorities are and where they are used to

  • Class attributes
  • Data descriptors
  • Instance attributes
  • Dataless Descriptors
  • Default __getattr__()

I also read the python documentation where I found the statement below: -

For example, bindings, the priority of the descriptor call depends on which descriptor methods are defined. Any combination of __get__() , __set__() and __delete__() can define a __delete__() . If this happens, do not define __get__() , then access to the attribute will return the handle itself, if the objects do not have a dictionary instance value. If the descriptor defines __set__() and / or __delete__() , this is a data descriptor; if it does not define any, it is a descriptor without data. Typically, data descriptors are defined as __get__() and __set__() , while descriptors without data have only the __get__() method.

Data descriptors with **__set__()** and **__get__()** , always defined, override the override in the instance dictionary. In contrast, non-data descriptors can be overridden by instances.

Python methods (including staticmethod() and classmethod() ) are implemented as descriptors without data. Accordingly, cases can override and override methods. This allows individual instances to acquire behaviors that differ from other instances of the same class.

Can someone give a small example to explain what the first paragraph ? And what does this mean by saying: override a redefinition in an instance dictionary ??

+7
source share
1 answer

Suppose you have a class:

 class C(object): dd = MyDataDescriptor() ndd = MyNonDataDescriptor() def __init__(self): self.__value = 1 

Let's look at the data descriptors first. If in your code you do:

 cobj = C() cobj.dd 

according to the paragraph above, the cobj.__dict__ object will always be redefined when accessing the dd attribute, i.e. __get__/__set__/__del__ methods of the descriptor object will always be used instead of the dictionary. The only exception is when the descriptor object does not define the __get__ method. Then, if there is a dd key in the cobj.__dict__ object, its value will be read if the descriptor object itself is not returned.

Now for descriptors without data. If in the code you call:

 cobj.ndd = 2 

then cobj.__dict__ hides the non-data descriptor, and the ndd attribute is always read from the cobj.__dict__ . So if you do this:

 cobj.ndd 

__get__ descriptor method will not be called. But if you remove the attribute from the dictionary:

 del cobj.ndd 

then the handle is returned, so the call

 cobj.ndd 

will call the __get__ method in the handle.

+4
source

All Articles