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.
The default behavior for attribute access is to get, set, or delete
the attribute from an object’s dictionary. For instance, a.x has a
lookup chain starting with a.__dict__['x'], then
type(a).__dict__['x'], and continuing through the base classes of
type(a) excluding metaclasses.
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).
The starting point for descriptor invocation is a binding, a.x. How
the arguments are assembled depends on a:
Direct Call
The simplest and least common call is when user code directly invokes
a descriptor method: x.__get__(a).
Instance Binding
If a is a new-style object instance, a.x is transformed into the
call: type(a).__dict__['x'].__get__(a, type(a)).
Class Binding
If A is a new-style class, A.x is transformed into the call:
A.__dict__['x'].__get__(None, A).
Super Binding
If a is an instance of super, then the binding
super(B, obj).m()
searches obj.__class__.__mro__ for the base class A
immediately preceding B and then invokes the descriptor with the
call: A.__dict__['m'].__get__(obj, A).
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.
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.
The property function is implemented as a data descriptor. Accordingly, instances cannot override the behavior of a property.

Comment:
The "super binding" section could be clarified. I think I understand what it says, but I think it could be said in a slightly less confusing way (e.g. by explaining why anyone would use an instance of super for anything).
Posted by infogami