Что такое протокол дескрипторов в Python

Ответ

Протокол дескрипторов в Python — это механизм, позволяющий объекту (дескриптору) управлять доступом к атрибутам другого объекта (владельца). Дескриптор должен реализовать один или несколько из следующих методов:

  • __get__(self, instance, owner): для получения значения атрибута.
  • __set__(self, instance, value): для установки значения атрибута.
  • __delete__(self, instance): для удаления атрибута.

Дескрипторы работают только тогда, когда они являются атрибутами класса, а не экземпляра.

Пример: дескриптор для валидации положительных чисел

class PositiveNumber:
    def __set_name__(self, owner, name):
        # Сохраняем имя атрибута, к которому привязан дескриптор
        self.private_name = '_' + name

    def __get__(self, instance, owner):
        return getattr(instance, self.private_name)

    def __set__(self, instance, value):
        if not isinstance(value, (int, float)) or value <= 0:
            raise ValueError(f"Значение должно быть положительным числом, а не {value}")
        setattr(instance, self.private_name, value)

class Product:
    price = PositiveNumber()
    quantity = PositiveNumber()

    def __init__(self, price, quantity):
        self.price = price
        self.quantity = quantity

# Использование
book = Product(150, 10)
print(book.price)  # 150

try:
    book.price = -50  # Вызовет ValueError
except ValueError as e:
    print(e)

Типы дескрипторов:

  • Data Descriptor: реализует __set__ или __delete__. Имеет приоритет над словарем экземпляра (__dict__).
  • Non-Data Descriptor: реализует только __get__. Имеет меньший приоритет.

Этот протокол является основой для многих возможностей Python, включая @property, @staticmethod, @classmethod и работу слотов (__slots__).