Brief introduction:
A Python descriptor is a language protocol in a modern class (inherited from Object) that provides a better and more elegant solution based on descriptors.
Python's Classmethod, Staticmethod, and property are all built on descriptors.
Descriptor's protocol:
An object that defines __set__, __get__, __delete__3 any of the methods in a method can be used as a descriptor.
Descriptor Categories:
Also defined __set__,__get__ is called data descriptor.
Only the definition of __get__ is called No-data descriptor.
2 different descriptors:
Data and non-data descriptors differ in how overrides is calculated with respect to entries in an instance ' s dictionary. If An instance ' s dictionary have a entry with the same name as a data descriptor, the data descriptor takes precedence. If An instance ' s dictionary have an entry with the same name as a Non-data descriptor, the dictionary entry takes Precedenc E.
In the Attrubuite lookup process:
If an object property has an attribute with the same name as Data-descriptor, Data-descriptor takes precedence over the object property.
If an object property has an attribute with the same name as No-data descriptor, the object property takes precedence.
Call to trigger Descriptor:
A descriptor can called directly by its method name. For example, d.__get__(obj)
.
Alternatively, it's more common for a descriptor to be invoked automatically upon attribute access. For Example, OBJ.D
looks Up d
in the dictionary of obj
. If d
defines the Method __get__ ()
, Then< Span class= "Pre" >d.__get__ (obj)
is invoked according to the precedence rules listed below.
The details of invocation depend on Whether obj
is An object or a class. Either, descriptors only work for new style objects and classes. A class is new style if it is a subclass Of Object
.
For objects, the machinery are in object.__getattribute__()
which transforms b.x
into type(b).__dict__[‘x‘].__get__(b, type(b))
. The implementation works through a precedence chain that gives data descriptors priority over instance variables, instance Variables priority over Non-data descriptors, and assigns lowest precedence to __getattr__()
if provided
The important points to remember is:
- Descriptors is invoked by the
__getattribute__()
method
- overriding
__getattribute__()
prevents automatic descriptor calls
__getattribute__()
IS-available with new style classes and objects
object.__getattribute__()
And make type.__getattribute__()
different calls to __get__()
.
- Data descriptors always override instance dictionaries.
- Non-data descriptors May is overridden by instance dictionaries.
Python Descriptor (Descriptor)