__get__(self, instance, owner)

The first parameter, instance, refers to the object from which the descriptor is being called. In our first example, this would mean the client object.

The owner parameter is a reference to the class of that object, which following our example (from the previous class diagram in The machinery behind descriptors section) would be ClientClass.

From the previous paragraph we conclude that the parameter named instance in the signature of __get__ is the object over which the descriptor is taking action, and owner is the class of instance. The avid reader might be wondering why is the signature define like this, after all the class can be taken from instance directly (owner = instance.__class__). There is an edge case—when the descriptor is called from the class (ClientClass), not from the instance (client), then the value of instance is None, but we might still want to do some processing in that case.

With the following simple code we can demonstrate the difference of when a descriptor is being called from the class, or from an instance. In this case, the __get__ method is doing two separate things for each case.

# descriptors_methods_1.py

class DescriptorClass:
def __get__(self, instance, owner):
if instance is None:
return f"{self.__class__.__name__}.{owner.__name__}"
return f"value for {instance}"


class ClientClass:

descriptor = DescriptorClass()

When we call it from ClientClass directly it will do one thing, which is composing a namespace with the names of the classes:

>>> ClientClass.descriptor
'DescriptorClass.ClientClass'

And then if we call it from an object we have created, it will return the other message instead:

>>> ClientClass().descriptor
'value for <descriptors_methods_1.ClientClass object at 0x...>'

In general, unless we really need to do something with the owner parameter, the most common idiom, is to just return the descriptor itself, when instance is None.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.139.83.7