Ответ
Декоратор в Python — это функция, которая принимает другую функцию в качестве аргумента, добавляет к ней некоторую функциональность и возвращает новую функцию. Это позволяет изменять или расширять поведение функций или методов, не изменяя их исходный код.
По сути, декоратор является "синтаксическим сахаром" для функций высшего порядка.
Запись с использованием @:
@my_decorator
def say_hello():
print("Hello!")
Эквивалентна следующей конструкции:
def say_hello():
print("Hello!")
say_hello = my_decorator(say_hello)
Основные сценарии использования:
- Логирование: Запись информации о вызове функции, ее аргументах и результате.
- Кеширование: Сохранение результатов выполнения функции для повторного использования (например,
functools.lru_cache). - Проверка прав доступа: Проверка, имеет ли пользователь право на выполнение определенного действия.
- Замер времени выполнения: Измерение производительности функции.
- Валидация данных: Проверка корректности аргументов, передаваемых в функцию.
Практический пример — декоратор для замера времени:
import time
def timing_decorator(func):
def wrapper(*args, **kwargs):
start_time = time.perf_counter()
result = func(*args, **kwargs)
end_time = time.perf_counter()
print(f"Функция '{func.__name__}' выполнилась за {end_time - start_time:.4f} секунд")
return result
return wrapper
@timing_decorator
def process_data(size: int):
"""Имитирует долгую обработку данных."""
time.sleep(1)
print(f"Обработано {size} элементов.")
return True
# Вызов декорированной функции
process_data(1000)
# Вывод:
# Обработано 1000 элементов.
# Функция 'process_data' выполнилась за 1.0012 секунд
Декораторы помогают следовать принципу DRY (Don't Repeat Yourself) и улучшают читаемость кода, отделяя основную бизнес-логику от вспомогательной (сквозной) функциональности.
Ответ 18+ 🔞
Слушай, ну вот объясняю тебе про декораторы в Python, как будто ты вчера родился, но уже хочешь в программисты. Это ж, блядь, такая штука, которая берёт твою обычную функцию, как вот эту, и натягивает на неё сверху, как презерватив, ещё один слой логики. А внутри-то функция та же самая, пизда, но теперь она в костюме супергероя.
Понимаешь, это как взять бутерброд и обернуть его в золотую фольгу. Вкус тот же, но подача — охуенно.
Вот смотри, этот собачий синтаксис с @:
@my_decorator
def say_hello():
print("Hello!")
Это просто пиздатый способ не писать вот эту хуйню каждый раз:
def say_hello():
print("Hello!")
say_hello = my_decorator(say_hello)
Одно и то же, ёпта! Просто первый вариант — красивый, а второй — для мазохистов.
А зачем это, спросишь, на хуй нужно?
- Логирование: Чтобы знать, кто, когда и с какими аргументами твою функцию ебал. Полезно, когда всё падает и ты не понимаешь, в каком месте.
- Кеширование: Чтобы не вычислять одно и то же по сто раз. Сказал «Привет, Вася» — запомнил. В следующий раз просто достал из кармана готовый ответ, а не думал заново.
- Проверка прав: Ты чё, сюда лезешь? У тебя есть пропуск? Нет? Тогда пошёл на хуй, функция не для тебя.
- Замер времени: Чтобы понять, почему твой код работает медленнее, чем черепаха в сиропе.
- Валидация данных: А ну-ка покажи, что ты мне в функцию суёшь! А, вот это говно? Не, братан, так не пойдёт.
Вот тебе живой пример, чтоб совсем понятно стало. Декоратор, который засекает время:
import time
def timing_decorator(func):
def wrapper(*args, **kwargs):
start_time = time.perf_counter()
result = func(*args, **kwargs) # А вот тут сама функция и работает
end_time = time.perf_counter()
print(f"Функция '{func.__name__}' выполнилась за {end_time - start_time:.4f} секунд")
return result
return wrapper
@timing_decorator
def process_data(size: int):
"""Имитирует долгую обработку данных."""
time.sleep(1)
print(f"Обработано {size} элементов.")
return True
# Вызов декорированной функции
process_data(1000)
# Вывод:
# Обработано 1000 элементов.
# Функция 'process_data' выполнилась за 1.0012 секунд
Видишь? Функция process_data просто спит и печатает. А декоратор @timing_decorator — это как хитрая жопа, которая стоит с секундомером и за всем следит. И главное — саму функцию process_data мы не трогали, ни строчки! Вот в чём, блядь, магия.
Короче, декораторы — это чтобы не повторять один и тот же код в каждой функции, как последний долбоёб. Принцип DRY, ёпта — Don't Repeat Yourself, или «Не будь говноедом». Отделил основную логику от всей этой обвязки — и живи спокойно, в рот меня чих-пых.