Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Что такое дескриптор?
Дескриптор — это объект, который определяет, как атрибут класса ведёт себя при доступе, присваивании или удалении. Он реализует один или несколько методов из протокола дескриптора: __get__, __set__ и __delete__.
Основные методы дескриптора
class Descriptor:
def __get__(self, obj, objtype=None):
# Вызывается при доступе к атрибуту
return "значение"
def __set__(self, obj, value):
# Вызывается при присваивании значения
pass
def __delete__(self, obj):
# Вызывается при удалении атрибута
pass
Типы дескрипторов
Data descriptor (дескриптор данных) — имеет методы __set__ и/или __delete__. Приоритет: сам дескриптор > словарь экземпляра.
Non-data descriptor (дескриптор без записи) — имеет только __get__. Приоритет: словарь экземпляра > дескриптор.
Практические примеры
1. Валидация значения (property)
class Age:
def __get__(self, obj, objtype=None):
return obj._age
def __set__(self, obj, value):
if not isinstance(value, int) or value < 0:
raise ValueError("Возраст должен быть положительным числом")
obj._age = value
class Person:
age = Age()
def __init__(self, age):
self.age = age
p = Person(25) # OK
p.age = -5 # ValueError
2. Ленивая инициализация
class LazyProperty:
def __init__(self, func):
self.func = func
self.name = func.__name__
def __get__(self, obj, objtype=None):
if obj is None:
return self
value = self.func(obj)
setattr(obj, self.name, value) # Кэшируем в __dict__
return value
class DataProcessor:
@LazyProperty
def processed_data(self):
print("Вычисляю данные...")
return expensive_operation()
3. Логирование доступа
class Logged:
def __init__(self, name):
self.name = name
def __get__(self, obj, objtype=None):
print(f"Доступ к {self.name}")
return obj.__dict__.get(self.name)
def __set__(self, obj, value):
print(f"Присвоение {self.name} = {value}")
obj.__dict__[self.name] = value
Зачем нужны дескрипторы?
- Контроль доступа — валидация, ограничение прав
- Мощная абстракция — реализованы через дескрипторы:
property,classmethod,staticmethod - Производительность — оптимизация горячих путей
- Паттерны — Observable, Proxy, Strategy
- ORM и фреймворки — Django ORM, SQLAlchemy используют дескрипторы для связей
Важные моменты
- Дескрипторы работают только при доступе через класс/экземпляр, не через
__dict__ - Data descriptors имеют приоритет над атрибутами экземпляра
@property— это встроенный дескриптор- Методы класса и статические методы — тоже дескрипторы