Понимание декораторов в Python
Декораторы в Python - это мощный и гибкий способ изменить поведение функции или класса. Они представляют собой вид функций высшего порядка, то есть они могут принимать функцию в качестве аргумента, добавить к ней некоторую функциональность и затем вернуть новую функцию. Это позволяет расширять функциональность функции без изменения ее основной логики.
Что такое декораторы?
Декораторы - это способ обернуть функцию другой функцией. Внутренняя функция, известная как "декоратор", обычно выполняет дополнительную обработку или функциональность до или после вызова исходной функции. Это может быть полезно для таких задач, как логирование, кэширование, аутентификация и многое другое.
Как работают декораторы
Декораторы в Python определяются с использованием символа @
, за которым следует имя функции-декоратора, размещенное непосредственно перед определением функции. Когда функция декорируется, функция-декоратор вызывается с исходной функцией в качестве аргумента, и результат функции-декоратора используется в качестве новой функции.
Вот простой пример декоратора, который логирует аргументы, передаваемые в функцию:
def log_args(func):
def wrapper(*args, **kwargs):
print(f"Calling {func.__name__} with args={args} and kwargs={kwargs}")
return func(*args, **kwargs)
return wrapper
@log_args
def add_numbers(a, b):
return a + b
result = add_numbers(2, 3)
print(result)
Это выведет:
Calling add_numbers with args=(2, 3) and kwargs={}
5
Композиция декораторов
Декораторы можно комбинировать, что позволяет применять несколько декораторов к одной функции. Декораторы применяются снизу вверх, причем самый внутренний декоратор применяется первым.
def uppercase(func):
def wrapper(*args, **kwargs):
result = func(*args, **kwargs)
return result.upper()
return wrapper
@uppercase
@log_args
def greet(name):
return f"Hello, {name}!"
print(greet("LabEx"))
Это выведет:
Calling greet with args=('LabEx',) and kwargs={}
HELLO, LABEX!
Понимание синтаксиса *args
и **kwargs
Синтаксис *args
и **kwargs
используется в декораторах, чтобы позволить декоратору обрабатывать функции с любым количеством позиционных и именованных аргументов. *args
собирает все позиционные аргументы в кортеж, а **kwargs
собирает все именованные аргументы в словарь.
Эта гибкость гарантирует, что декоратор можно применить к широкому диапазону функций, независимо от их сигнатуры аргументов.