Python › Descriptors & Properties

What is a descriptor, and which dunder methods define the descriptor protocol?

Intermediate

Answer

A descriptor is any object implementing __get__, __set__, and/or __delete__, placed as a CLASS attribute — when accessed through an instance, Python automatically calls these methods instead of doing a plain attribute lookup, giving you full control over get/set/delete behavior; @property is actually implemented USING descriptors under the hood.
class PositiveNumber:
    def __set_name__(self, owner, name):
        self.name = f"_{name}"
    def __get__(self, instance, owner):
        return getattr(instance, self.name)
    def __set__(self, instance, value):
        if value < 0:
            raise ValueError("Must be positive")
        setattr(instance, self.name, value)

class Product:
    price = PositiveNumber()  # a reusable descriptor
Real-world example Building a REUSABLE validation rule (like PositiveNumber) that can be applied to multiple attributes across different classes.

Common follow-ups: What's the practical advantage of a reusable descriptor class over writing a separate @property for each validated attribute?