Invoking Descriptors

In general, a descriptor is an object attribute with ``binding behavior'', one whose attribute access has been overridden by methods in the descriptor protocol: __get__(), __set__(), and __delete__(). If any of those methods are defined for an object, it is said to be a descriptor.


However, if the looked-up value is an object defining one of the descriptor methods, then Python may override the default behavior and invoke the descriptor method instead. Where this occurs in the precedence chain depends on which descriptor methods were defined and how they were called. Note that descriptors are only invoked for new style objects or classes (ones that subclass object() or type()).


Direct Call

Instance Binding
If binding to a new-style object instance, a.x is transformed into the call: type(a).__dict__['x'].__get__(a, type(a)).

Class Binding
If binding to a new-style class, A.x is transformed into the call: A.__dict__['x'].__get__(None, A).

Super Binding

For instance bindings, the precedence of descriptor invocation depends on the which descriptor methods are defined. Data descriptors define both __get__() and __set__(). Non-data descriptors have just the __get__() method. Data descriptors always override a redefinition in an instance dictionary. In contrast, non-data descriptors can be overridden by instances.


