Ответ
Декоратор — это структурный паттерн проектирования, который позволяет динамически добавлять новую функциональность объектам, оборачивая их в специальные классы-обертки.
Основная идея — следование принципу открытости/закрытости: можно расширять поведение объекта, не изменяя его исходный код.
Как это работает
- Создается интерфейс, общий для «декорируемого» объекта и «декоратора».
- Класс-декоратор содержит ссылку на декорируемый объект.
- Декоратор выполняет свою дополнительную логику до или после вызова метода оригинального объекта.
Пример в Python
В Python идея декоратора элегантно реализуется через синтаксис @, который чаще всего применяется к функциям.
import functools
import time
# Декоратор для измерения времени выполнения функции
def timer(func):
@functools.wraps(func) # Сохраняет метаданные (имя, docstring) исходной функции
def wrapper(*args, **kwargs):
start_time = time.perf_counter()
result = func(*args, **kwargs)
end_time = time.perf_counter()
run_time = end_time - start_time
print(f"Функция '{func.__name__}' выполнилась за {run_time:.4f} с")
return result
return wrapper
@timer
def process_data(data):
"""Имитирует долгую обработку данных."""
time.sleep(1)
return f"Обработано {len(data)} элементов"
print(process_data([1, 2, 3]))
# Вывод:
# Функция 'process_data' выполнилась за 1.0012 с
# Обработано 3 элементов
Основные преимущества
- Гибкость: Функциональность можно добавлять и убирать во время выполнения.
- Компонуемость: Декораторы можно применять цепочкой, комбинируя их поведение.
- Избегание наследования: Позволяет избежать создания множества подклассов для каждой комбинации поведений.
Ответ 18+ 🔞
Давай разберёмся с этим декоратором, а то народ его как будто в первый раз видит, блядь. Ну, паттерн такой, сука, структурный. Представь, что у тебя есть объект — ну, как есть, простой, голый, без изысков. А тебе надо ему на лету, ёпта, новую фичу прикрутить. Не лезть же в его кишки, переписывать код? Вот для этого и нужен декоратор, хитрая жопа.
Работает он по принципу «открытости/закрытости», что в переводе на русский значит: «расширяй, но не трогай то, что уже работает, а то сломаешь, мудак». Суть проста, как три копейки:
- Берёшь интерфейс, общий для всех — и для того, кого декорируешь, и для самой обёртки.
- Класс-декоратор — он как хитрая куртка. Внутри у него ссылка на тот самый объект, который он оборачивает.
- И вот когда вызываешь метод, декоратор сначала делает своё дело (или после), а потом уже передаёт управление дальше, тому, кто внутри.
А в Python, блядь, это вообще красота, потому что для функций есть специальный синтаксис @. Смотри, как это выглядит на практике, без всякой воды.
import functools
import time
# Декоратор, который засекает время, как часы с кукушкой, блядь
def timer(func):
@functools.wraps(func) # Эта штука сохраняет имя и описание оригинальной функции, а то всё потеряется, ёпта
def wrapper(*args, **kwargs):
start_time = time.perf_counter()
result = func(*args, **kwargs) # А вот тут вызывается сама функция, которую мы обернули
end_time = time.perf_counter()
run_time = end_time - start_time
print(f"Функция '{func.__name__}' выполнилась за {run_time:.4f} с")
return result
return wrapper
@timer # Вешаем наш секундомер на функцию — и всё, пиздец, теперь она под наблюдением
def process_data(data):
"""Имитирует долгую обработку данных."""
time.sleep(1)
return f"Обработано {len(data)} элементов"
print(process_data([1, 2, 3]))
# Вывод:
# Функция 'process_data' выполнилась за 1.0012 с
# Обработано 3 элементов
Видишь? Написали один раз timer, и теперь на любую функцию можно нацепить этот @timer, и она автоматом будет отчитываться, сколько там возилась. Красота, ёперный театр!
Чем это, блядь, хорошо?
- Гибкость, овердохуища: Добавляй и снимай функциональность прямо на ходу, как перчатки.
- Компонуемость: Их можно, сука, цеплять друг на друга, как матрёшек.
@декоратор1 @декоратор2 def func()— и поехали. - Не надо плодить наследников: А то будешь как дурак создавать класс
КлассСФичейА,КлассСФичейБ,КлассСФичамиАиБ, а потом ещё иКлассСФичамиАБиВ. Пиздец, а не иерархия. А тут — обернул и пошёл.
Вот и весь сказ, блядь. Не такой уж он и страшный, этот декоратор. Главное — понять принцип обёртки, а дальше — только твоя фантазия ограничивает, что можно накрутить.