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, которые можно адаптировать к различным потребностям.