面向高级程序员的 Python 装饰器指南
Python 装饰器是一种功能强大且灵活的工具,可用于修改函数或方法的行为。它们允许程序员以干净、可读且可维护的方式扩展或更改可调用对象的功能。本文探讨与 Python 装饰器相关的高级概念,包括嵌套装饰器、装饰器参数和基于类的装饰器。
什么是装饰器?
装饰器是修改另一个函数行为的函数。它们包装另一个函数以扩展其行为,而无需明确修改其代码。装饰器使用 @decorator_name
语法定义,并放置在函数定义之上。
基本装饰器语法
一个简单的装饰器以一个函数作为参数,定义一个添加一些行为的内部函数,然后返回该内部函数。
def my_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
@my_decorator
def say_hello():
print("Hello!")
say_hello()
带参数的装饰函数
通过接受参数,装饰器可以变得更加灵活。要创建这样的装饰器,您需要编写一个返回装饰器的函数。这可以为装饰器添加更多动态行为。
def repeat(num_times):
def decorator_repeat(func):
def wrapper(*args, **kwargs):
for _ in range(num_times):
func(*args, **kwargs)
return wrapper
return decorator_repeat
@repeat(num_times=3)
def greet(name):
print(f"Hello, {name}!")
greet("Alice")
嵌套装饰器
装饰器可以嵌套使用,以组合多种行为。例如,我们可以在一个函数上使用两个或多个装饰器。
def uppercase_decorator(func):
def wrapper(*args, **kwargs):
result = func(*args, **kwargs)
return result.upper()
return wrapper
def repeat_decorator(func):
def wrapper(*args, **kwargs):
result = func(*args, **kwargs)
return result + result
return wrapper
@repeat_decorator
@uppercase_decorator
def say_word(word):
return word
print(say_word("hello"))
基于类的装饰器
在 Python 中,装饰器也可以通过使用 __call__
方法作为类来实现。当您需要更复杂的状态管理和行为时,基于类的装饰器非常有用。
class CountCalls:
def __init__(self, func):
self.func = func
self.num_calls = 0
def __call__(self, *args, **kwargs):
self.num_calls += 1
print(f"Call {self.num_calls} of {self.func.__name__!r}")
return self.func(*args, **kwargs)
@CountCalls
def say_hello():
print("Hello!")
say_hello()
say_hello()
使用 functools.wraps
保存元数据
当您编写装饰器时,被装饰的函数会丢失其原始元数据,例如其名称和文档字符串。 functools.wraps
装饰器可用于将原始函数的元数据复制到包装函数。
from functools import wraps
def my_decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
print("Wrapper function executed before", func.__name__)
return func(*args, **kwargs)
return wrapper
@my_decorator
def display_info(name, age):
"""Displays name and age."""
print(f"display_info ran with arguments ({name}, {age})")
print(display_info.__name__) # Output: display_info
print(display_info.__doc__) # Output: Displays name and age.
结论
Python 装饰器是一项强大的功能,可实现灵活的代码设计和行为修改。高级用法(例如嵌套装饰器、带参数的装饰器和基于类的装饰器)可以为 Python 程序提供更多功能和可读性。通过正确理解和使用装饰器,开发人员可以编写更简洁、高效且可读的代码。