Descriptors And Direct Access: Python Reference
Solution 1:
By accessing the descriptor on self
you invoked __get__
already. The value 42
is being returned.
For any attribute access, Python will look to the type of the object (so type(self)
here) to see if there is a descriptor object there (an object with a .__get__()
method, for example), and will then invoke that descriptor.
That's how methods work; a function object is found, which has a .__get__()
method, which is invoked and returns a method object bound to self.
If you wanted to access the descriptor directly, you'd have to bypass this mechanism; access x
in the __dict__
dictionary of Owner
:
>>>Owner.__dict__['x']
<__main__.MyDescriptor object at 0x100e48e10>
>>>Owner.__dict__['x'].__get__(None, Owner)
hello
42
This behaviour is documented right above where you saw the x.__get__(a)
direct call:
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 witha.__dict__['x']
, thentype(a).__dict__['x']
, and continuing through the base classes oftype(a)
excluding metaclasses.
The Direct Call scenario in the documentation only applies when you have a direct reference to the descriptor object (not invoked); the Owner.__dict__['x']
expression is such a reference.
Your code on the other hand, is an example of the Instance Binding scenario:
Instance Binding If binding to an object instance,
a.x
is transformed into the call:type(a).__dict__['x'].__get__(a, type(a))
.
Post a Comment for "Descriptors And Direct Access: Python Reference"