Декораторы
Декораторы в Python — это мощный инструмент для модификации поведения функций, позволяющий добавлять функциональность и улучшать читаемость кода без изменения его структуры.

Декораторы в Python — это настоящие волшебники, которые могут изменить поведение функций, не меняя их исходный код. Представь, что у тебя есть супергерой, который может надеть на себя плащ и стать невидимым, но при этом продолжает делать свои героические дела. Вот декораторы и есть такие плащи для функций!
Что такое декоратор?
Декоратор — это функция, которая принимает другую функцию в качестве аргумента и возвращает новую функцию с изменённым поведением. Это как если бы ты взял обычный бутерброд и добавил к нему немного авокадо — он стал не только вкуснее, но и полезнее!
Пример простого декоратора
Давай создадим простой декоратор, который будет выводить сообщение до и после выполнения функции:
def my_decorator(func):
def wrapper():
print("Что-то происходит до вызова функции.")
func()
print("Что-то происходит после вызова функции.")
return wrapper
@my_decorator
def say_hello():
print("Привет!")
say_hello()
Когда ты вызываешь say_hello(), на самом деле вызывается wrapper(), который оборачивает нашу функцию. Это как если бы ты пришёл на вечеринку, а тебя встречают с тортом и фейерверками!
Аргументы в декораторах
Но что делать, если твоя функция принимает аргументы? Не переживай! Мы можем сделать наш декоратор более универсальным.
Декоратор с аргументами
Вот пример декоратора, который принимает аргументы и передаёт их функции:
def repeat(num_times):
def decorator_repeat(func):
def wrapper(*args, **kwargs):
for in range(numtimes):
func(*args, **kwargs)
return wrapper
return decorator_repeat
@repeat(3)
def greet(name):
print(f"Привет, {name}!")
greet("Алексей")
В этом примере функция greet будет вызываться трижды. Если бы у тебя была возможность повторять свои любимые моменты в жизни, ты бы воспользовался ею, не так ли?
Встроенные декораторы
Python предоставляет несколько встроенных декораторов, таких как @staticmethod и @classmethod. Они помогают нам работать с методами классов.
Пример использования @classmethod
Давай посмотрим, как работает @classmethod:
class MyClass:
class_variable = "Я класс-атрибут!"
@classmethod
def class_method(cls):
print(cls.class_variable)
MyClass.class_method()
Здесь class_method получает ссылку на сам класс через параметр cls. Это как если бы ты был в классе и мог передавать свои заметки другим ученикам!
Композиция декораторов
Ты можешь комбинировать несколько декораторов. Это похоже на то, как ты можешь добавить разные топпинги к своему мороженому: шоколад, орехи и вишенку сверху!
Пример композиции декораторов
def bold(func):
def wrapper(*args, **kwargs):
return f"<b>{func(*args, **kwargs)}</b>"
return wrapper
def italic(func):
def wrapper(*args, **kwargs):
return f"<i>{func(*args, **kwargs)}</i>"
return wrapper
@bold
@italic
def say_hi(name):
return f"Привет, {name}!"
print(say_hi("Мария"))

В результате мы получаем: Привет, Мария!. Это как если бы ты одел своего друга в костюм и добавил к нему стильные очки!
Заключительные мысли о декораторах
Декораторы — это мощный инструмент для программистов. Они позволяют добавлять функциональность к существующим функциям без изменения их кода. Как говорит старая пословица: "Не меняй то, что работает!" Используй декораторы, чтобы сделать свой код более чистым и читаемым.
Теперь ты знаешь о декораторах больше! Надеюсь, ты сможешь использовать их в своих проектах. Помни: с великой силой приходит великая ответственность… и много возможностей для улучшения кода!
Задания для закрепления материала
Задача 1: Создание логирующего декоратора
Создай декоратор, который будет записывать в файл логи о вызовах функции: время вызова и переданные аргументы. Протестируй его на функции, которая принимает несколько аргументов.
Задача 2: Декоратор для ограничения времени выполнения
Напиши декоратор, который будет ограничивать время выполнения функции. Если функция не завершится за заданное время, она должна выбрасывать исключение. Протестируй на функции, которая выполняется долго.
Задача 3: Декоратор для кэширования результатов
Создай декоратор, который будет кэшировать результаты функции. Если функция вызывается с теми же аргументами, возвращай закэшированный результат вместо повторного вычисления. Проверь его работу на функции, которая выполняет дорогостоящие вычисления.
Задача 4: Декоратор для проверки прав доступа
Разработай декоратор, который будет проверять права доступа пользователя перед выполнением функции. Если у пользователя нет необходимых прав, функция должна возвращать сообщение об ошибке. Протестируй на функции, которая требует определенных прав.
Задача 5: Декоратор для изменения возвращаемого значения
Напиши декоратор, который будет изменять возвращаемое значение функции. Например, если функция возвращает число, декоратор должен умножать его на 2. Проверь его работу на функции, которая возвращает случайное число.