Декораторы Python
Декоратор — это продвинутая возможность в Python, используемая длядинамического расширения функциональности функций или классов без изменения исходного кода функции。
По сути, декоратор — это функция: он принимает функцию в качестве аргумента и возвращает новую функцию (обычно улучшенную версию исходной функции).
Декораторы применяются с помощью синтаксиса@decorator_name, размещаемого перед определением функции или метода.
Python также предоставляет некоторые встроенные декораторы, такие как@staticmethodи@classmethod。
Типичные случаи использования:
- Логирование:Запись информации о вызовах функций, параметрах и возвращаемых значениях
- Статистика производительности:Измерение времени выполнения функции
- Контроль доступа:Ограничение прав доступа к функции
- Кэширование:Кэшировать результаты функции для повышения производительности
Базовый синтаксис
Основная идея декоратора:использование одной функции для "обёртывания" другой функции。
Синтаксис
def wrapper(*args, **kwargs):
# Перед вызовом
print("Перед выполнением")
result = original_function(*args, **kwargs)
# После вызова
print("После выполнения")
return result
return wrapper
@decorator_function
def target_function():
print("Выполнение исходной функции")
Пояснение:
decorator_function: функция-декоратор (получает исходную функцию)wrapper: функция-обёртка (фактически выполняется)@decorator_function: эквивалентно замене функции
Эквивалентная форма:
target_function = decorator_function(target_function)
👉 При вызовеtarget_function(), фактически выполняетсяwrapper()
Использование декораторов
Декораторы применяются с помощью@синтаксического сахара, размещаемого перед определением функции:
@time_logger
def target_function():
pass
Эквивалентно:
def target_function():
pass
target_function = time_logger(target_function)
Этот механизм позволяет единообразно добавлять функциональность (например, логирование, проверку прав и т. д.) без изменения исходной функции.
Пример: вывод логов
def wrapper():
print("Before function execution")
func()
print("After function execution")
return wrapper
@my_decorator
def say_hello():
print("Hello!")
say_hello()
Вывод:
函数执行前 Hello! 函数执行后
my_decoratorПолучаетsay_hello@my_decoratorЗаменяет исходную функцию
Декораторы с параметрами
Если у исходной функции есть параметры, нужно вwrapperиспользовать*args, **kwargs:
Пример
def wrapper(*args, **kwargs):
print("Перед выполнением")
func(*args, **kwargs)
print("После выполнения")
return wrapper
@my_decorator
def greet(name):
print(f"Привет, {name}!")
greet("Alice")
Вывод:
执行前 Hello, Alice! 执行后
Пояснение:Использование*args, **kwargsможет принимать функции с любым количеством параметров.
Декораторы с параметрами (продвинутый уровень)
def decorator(func):
def wrapper(*args, **kwargs):
for _ in range(num_times):
func(*args, **kwargs)
return wrapper
return decorator
@repeat(3)
def say_hello():
print("Hello!")
say_hello()
Пояснение:Это «фабрика декораторов»; внешняя функция используется для получения параметров.
Hello! Hello! Hello!
Декораторы классов
Помимо функций, декораторы также можно применять к классам.
Декоратор класса получает класс и возвращает изменённый класс или класс-обёртку.
- Расширять методы класса
- Управлять процессом создания экземпляров
- Реализовывать функциональность, такую как синглтоны и логирование
Декораторы классов на основе функций
Пример
class Wrapper:
def __init__(self, *args, **kwargs):
self.wrapped = cls(*args, **kwargs)
def __getattr__(self, name):
return getattr(self.wrapped, name)
def display(self):
print("Перед вызовом")
self.wrapped.display()
print("После вызова")
return Wrapper
@log_class
class MyClass:
def display(self):
print("Исходный метод")
obj = MyClass()
obj.display()
Before call Original method After call
Декораторы классов, основанные на классах
Пример: шаблон «Одиночка»
def __init__(self, cls):
self.cls = cls
self.instance = None
def __call__(self, *args, **kwargs):
if self.instance is None:
self.instance = self.cls(*args, **kwargs)
return self.instance
@SingletonDecorator
class Database:
def __init__(self):
print("Инициализация")
db1 = База данных()
db2 = База данных()
print(db1 is db2)
初始化 True
Встроенные декораторы
Часто используемые встроенные декораторы:
- @staticmethod: определяет статический метод
- @classmethod: определяет метод класса
- @property: превращает метод в свойство
Пример
@staticmethod
def static_method():
print("Статический метод")
@classmethod
def class_method(cls):
print(cls.__name__)
@property
def name(self):
return self._name
@name.setter
def name(self, value):
self._name = value
Наложение нескольких декораторов
Несколько декораторовоборачивают снизу вверх на этапе определения,и выполняются сверху вниз на этапе вызова:
Пример
def wrapper():
print("Decorator 1")
func()
return wrapper
def decorator2(func):
def wrapper():
print("Decorator 2")
func()
return wrapper
@decorator1
@decorator2
def say_hello():
print("Hello!")
say_hello()
Итоговый вывод:
Decorator 1 Decorator 2 Hello!
Краткое резюме
Decorator = a function that wraps a function + extending functionality without modifying the original code
- Синтаксис @ по сути представляет собой замену функции
- wrapper — это функция, которая фактически выполняется
- Рекомендуется использовать *args, **kwargs для большей универсальности
- Поддерживает функции, классы и даже декораторы с параметрами