Дескрипторы — это объекты, которые контролируют доступ к атрибутам класса. Они реализуют один или несколько специальных методов: __get__, __set__ и __delete__. Этот механизм фундаментален для того, как Python управляет поиском атрибутов внутри.
Встроенные средства Python активно используют дескрипторы:
property() — контролирует логику геттеров, сеттеров и делитеров для атрибутовclassmethod() и staticmethod() — изменяют способ привязки методов к классам или экземплярам__slots__ — ограничивает и оптимизирует хранение атрибутов экземпляраDjango ORM использует дескрипторы для определения полей модели. Когда ты объявляешь:
class MyModel(models.Model):
name = models.CharField(max_length=100)
CharField — это дескриптор, который прозрачно управляет валидацией, маппингом столбца базы данных и присвоением значений.
SQLAlchemy использует дескрипторы для ленивой загрузки — связанные объекты загружаются из базы данных только при первом обращении, без какого-либо дополнительного кода со стороны разработчика.
Простой дескриптор для валидированного доступа к атрибутам:
class PositiveNumber:
def __set_name__(self, owner, name):
self.name = name
def __get__(self, obj, objtype=None):
return getattr(obj, f"_{self.name}", None)
def __set__(self, obj, value):
if value <= 0:
raise ValueError(f"{self.name} must be positive")
setattr(obj, f"_{self.name}", value)
Дескрипторы позволяют тебе инкапсулировать переиспользуемую логику атрибутов на уровне класса, сохраняя код чистым и придерживаясь принципа DRY. Вместо того чтобы дублировать логику валидации или преобразования данных во множестве свойств, ты определяешь её один раз в дескрипторе и применяешь где угодно — именно поэтому крупные фреймворки на них полагаются.
Метод __set_name__ в дескрипторе вызывается автоматически, когда экземпляр дескриптора присваивается атрибуту класса, позволяя ему захватить имя атрибута без явного указания.
Новый — ещё не проверен сообществом
Вы