I am trying to understand what Python's descriptors are and what they are useful for. I understand how they work, but here are my doubts. Consider the following code:
class Celsius(object): def __init__(self, value=0.0): self.value = float(value) def __get__(self, instance, owner): return self.value def __set__(self, instance, value): self.value = float(value) class Temperature(object): celsius = Celsius()
Why do I need the descriptor class?
What is instance
and owner
here? (in __get__
). What is the purpose of these parameters?
How would I call/use this example?
Python __get__ Magic Method. Python's __get__() magic method defines the dynamic return value when accessing a specific instance and class attribute. It is defined in the attribute's class and not in the class holding the attribute (= the owner class).
Python descriptors are a way to create managed attributes. Among their many advantages, managed attributes are used to protect an attribute from changes or to automatically update the values of a dependant attribute. Descriptors increase an understanding of Python, and improve coding skills.
The Cliff's Notes version: descriptors are a low-level mechanism that lets you hook into an object's attributes being accessed. Properties are a high-level application of this; that is, properties are implemented using descriptors.
“Descriptors” are objects that describe some attribute of an object. They are found in the dictionary of type objects.
The descriptor is how Python's property
type is implemented. A descriptor simply implements __get__
, __set__
, etc. and is then added to another class in its definition (as you did above with the Temperature class). For example:
temp=Temperature() temp.celsius #calls celsius.__get__
Accessing the property you assigned the descriptor to (celsius
in the above example) calls the appropriate descriptor method.
instance
in __get__
is the instance of the class (so above, __get__
would receive temp
, while owner
is the class with the descriptor (so it would be Temperature
).
You need to use a descriptor class to encapsulate the logic that powers it. That way, if the descriptor is used to cache some expensive operation (for example), it could store the value on itself and not its class.
An article about descriptors can be found here.
EDIT: As jchl pointed out in the comments, if you simply try Temperature.celsius
, instance
will be None
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With