Декораторы классов — мощный инструмент для создания элегантного ООП-кода в Python. Но чтобы использовать их эффективно, нужно понимать разницу между @classmethod, @staticmethod и @property. Разберём каждый на реалистичных примерах с сравнением подходов.
@property: Контролируемый доступ к атрибутам
Проблема без декоратора:
Без @property для валидации данных приходится использовать методы-сеттеры, что ломает естественность работы с атрибутами.
class UserWithoutProperty:
def __init__(self, name):
self.name = name
self._age = 0
def get_age(self):
return self._age
def set_age(self, value):
if not (0 < value < 120):
raise ValueError("Invalid age")
self._age = value
# Неудобное использование:
user = UserWithoutProperty("Alice")
user.set_age(25) # Вызов метода вместо присваивания
print(user.get_age()) # Не как обычное свойствоРешение с @property:
Декоратор превращает методы в атрибуты с логикой:
class User:
def __init__(self, name):
self.name = name
self._age = 0
@property
def age(self):
return f"Возраст: {self._age} лет"
@age.setter
def age(self, value):
if not (0 < value < 120):
raise ValueError("Недопустимый возраст")
self._age = value
# Естественное использование:
user = User("Bob")
user.age = 30 # Вызывает сеттер с валидацией
print(user.age) # Возраст: 30 лет (геттер форматирует данные)Плюсы:
Инкапсуляция внутреннего состояния
Валидация при установке значений
Ленивые вычисления (например, загрузка данных по требованию)
Совместимость с обычным доступом к атрибутам
Минусы:
Избыточность для простых атрибутов без логики
Неочевидность побочных эффектов при чтении
