def outer_decorator(arg1, arg2):
def middle_decorator(func):
def inner_wrapper(*args, **kwargs):
# Логика до вызова функции
print(f"Внешний декоратор: {arg1}, {arg2}")
result = func(*args, **kwargs)
# Логика после вызова функции
return result
return inner_wrapper
return middle_decorator
@outer_decorator("hello", "world")
def my_function(x):
return x * 2
print(my_function(5))
В этом примере `outer_decorator` принимает аргументы и возвращает `middle_decorator`. `middle_decorator` принимает декорируемую функцию и возвращает `inner_wrapper`, который, в свою очередь, выполняет код до и после вызова исходной функции.
Создание сложного декоратора с несколькими уровнями вложенности в Python предполагает использование функций, возвращающих функции. Это позволяет создавать декораторы, которые принимают аргументы и/или настраиваются перед тем, как применить их к декорируемой функции. Вот как это можно сделать:
def decorator_factory(*decorator_args, **decorator_kwargs):
"""
Фабрика декораторов. Принимает аргументы для настройки декоратора.
Возвращает сам декоратор (функцию, принимающую декорируемую функцию).
"""
print(f"decorator_factory: args={decorator_args}, kwargs={decorator_kwargs}")
def actual_decorator(func):
"""
Сам декоратор. Принимает декорируемую функцию.
Возвращает обернутую функцию.
"""
print(f"actual_decorator: func={func.__name__}")
def wrapper(*args, **kwargs):
"""
Обернутая функция. Выполняет логику декоратора до и после вызова декорируемой функции.
"""
print(f"wrapper: args={args}, kwargs={kwargs}")
# Логика перед вызовом декорируемой функции
print("Декоратор: Перед вызовом функции.")
result = func(*args, **kwargs) # Вызов декорируемой функции
# Логика после вызова декорируемой функции
print("Декоратор: После вызова функции.")
return result
print("actual_decorator: returning wrapper")
return wrapper
print("decorator_factory: returning actual_decorator")
return actual_decorator
# Пример использования
@decorator_factory("arg1", "arg2", keyword1="value1", keyword2="value2")
def my_function(a, b):
"""Пример декорируемой функции."""
print(f"my_function: a={a}, b={b}")
return a + b
result = my_function(10, 20)
print(f"Результат: {result}")
Разберем код:
decorator_factory: Это фабрика декораторов. Она принимает аргументы (*decorator_args, **decorator_kwargs), которые используются для настройки декоратора. Она возвращает функцию actual_decorator. При вызове @decorator_factory(...) происходит выполнение этого кода.actual_decorator: Это сам декоратор. Он принимает декорируемую функцию (func) в качестве аргумента. Он возвращает функцию wrapper. Этот код выполняется во время применения декоратора (@).wrapper: Это обернутая функция. Она принимает те же аргументы, что и декорируемая функция (*args, **kwargs). Она выполняет логику до и после вызова декорируемой функции. Этот код выполняется каждый раз, когда вызывается декорированная функция.Как это работает:
@decorator_factory("arg1", keyword1="value1") над функцией my_function, вызывается decorator_factory с аргументами "arg1" и keyword1="value1".decorator_factory возвращает функцию actual_decorator.actual_decorator к my_function, передавая ее в качестве аргумента. То есть, actual_decorator(my_function).actual_decorator создает функцию wrapper, которая оборачивает my_function.actual_decorator возвращает wrapper.my_function(10, 20), на самом деле вызывается wrapper(10, 20).wrapper выполняет свою логику (печатает "Декоратор: Перед вызовом функции."), затем вызывает my_function(10, 20).my_function выполняет свою логику (печатает "my_function: a=10, b=20" и возвращает 30).wrapper выполняет свою логику после вызова функции (печатает "Декоратор: После вызова функции.") и возвращает результат, полученный от my_function (30).Преимущества:
Этот шаблон позволяет создавать гибкие и мощные декораторы в Python, которые можно адаптировать к различным потребностям.