Cover Image for Python descriptors
185 views

Python descriptors

Descriptors are a powerful and advanced feature in Python that allow you to define custom behavior for attribute access, assignment, and deletion. They are typically used to control how values are stored or retrieved from attributes of an object. Descriptors are often seen in Python classes as methods defined with special names such as __get__, __set__, and __delete__. Here’s an overview of Python descriptors:


__get__(self, instance, owner):

  • This method is called when you access the descriptor’s attribute using dot notation (e.g., obj.attr).
  • self refers to the descriptor instance itself.
  • instance is the instance of the object that the descriptor is bound to.
  • owner is the class that owns the descriptor (the class where it’s defined).


__set__(self, instance, value):

  • This method is called when you assign a value to the descriptor’s attribute (e.g., obj.attr = value).
  • self refers to the descriptor instance itself.
  • instance is the instance of the object that the descriptor is bound to.
  • value is the value being assigned to the attribute.


__delete__(self, instance):

  • This method is called when you delete the descriptor’s attribute (e.g., del obj.attr).
  • self refers to the descriptor instance itself.
  • instance is the instance of the object that the descriptor is bound to.

Here’s an example of a descriptor that ensures a value is always non-negative:

Python
class NonNegative:
    def __get__(self, instance, owner):
        return instance._value

    def __set__(self, instance, value):
        if value < 0:
            raise ValueError("Value cannot be negative")
        instance._value = value

class Number:
    def __init__(self, value):
        self._value = value

    # Attach the descriptor to the 'value' attribute
    value = NonNegative()

# Usage
num = Number(10)
print(num.value)  # Accessing the descriptor
num.value = 20   # Setting the descriptor
print(num.value)

This example, the NonNegative descriptor ensures that the value attribute of the Number class is always non-negative. It does this by implementing the __get__ and __set__ methods. When you try to set a negative value, it raises a ValueError.

Descriptors are often used to implement properties, validators, and computed attributes. They provide a way to encapsulate attribute access and provide custom behavior without the need for explicit getter and setter methods. Understanding descriptors is useful when working with advanced Python classes and custom data structures.

YOU MAY ALSO LIKE...

The Tech Thunder

The Tech Thunder

The Tech Thunder


COMMENTS