Декораторы в Python — это мощный инструмент, позволяющий модифицировать поведение функций или методов без изменения их кода. Декораторы обеспечивают простой синтаксис для расширения и модификации поведения функций и методов, что делает код более читаемым и эффективным.
Теоретическая часть
Определение декоратора
Декоратор в Python — это функция, которая принимает другую функцию в качестве аргумента и возвращает новую функцию, расширяя поведение исходной функции без её изменения.
Создание декоратора
Чтобы создать декоратор, необходимо определить функцию, которая принимает другую функцию в качестве аргумента и возвращает функцию. Внутри декоратора можно определить вложенную функцию, которая будет оберткой для исходной функции, позволяя добавлять к ней дополнительное поведение.
Примеры кода
# Пример простого декоратора
def simple_decorator(func):
def wrapper():
print("Something is happening before the function is called.")
func()
print("Something is happening after the function is called.")
return wrapper
@simple_decorator
def say_hello():
print("Hello!")
say_hello()
Практические задания
1. Создайте декоратор timer, который измеряет время выполнения декорируемой функции и выводит его.
2. Напишите декоратор debug, который выводит имя вызываемой функции и её аргументы, а после выполнения функции выводит её результат.
Решение задания
# Декоратор timer
import time
def timer(func):
def wrapper(*args, **kwargs):
start_time = time.time()
result = func(*args, **kwargs)
end_time = time.time()
print(f"Function {func.__name__} took {end_time - start_time} seconds to complete.")
return result
return wrapper
@timer
def long_running_function():
time.sleep(2)
long_running_function()
# Декоратор debug
def debug(func):
def wrapper(*args, **kwargs):
args_repr = [repr(a) for a in args]
kwargs_repr = [f"{k}={v!r}" for k, v in kwargs.items()]
signature = ", ".join(args_repr + kwargs_repr)
print(f"Calling {func.__name__}({signature})")
result = func(*args, **kwargs)
print(f"{func.__name__} returned {result!r}")
return result
return wrapper
@debug
def greeting(name, age=None):
return f"Hello {name}!{' You are ' + str(age) + ' years old.' if age else ''}"
greeting("John", age=30)