Python 装饰器是 Python 语言中最优雅也最容易被误解的特性之一。理解它的关键在于:函数在 Python 中是一等公民,可以被当作参数传递、作为返回值返回。
装饰器的本质
装饰器本质就是一个接收函数、返回新函数的普通函数:
def my_decorator(func): def wrapper(*args, **kwargs): print("调用前") result = func(*args, **kwargs) print("调用后") return result return wrapper
@my_decorator def hello(): print("Hello, Stellar!")
|
上面的 @my_decorator 语法糖等价于:
hello = my_decorator(hello)
|
带参数的装饰器
当装饰器本身需要参数时,需要再包一层:
def repeat(times): def decorator(func): def wrapper(*args, **kwargs): for _ in range(times): func(*args, **kwargs) return wrapper return decorator
@repeat(3) def say(): print("Hi")
|
直接返回 wrapper 会丢失原函数的 __name__、__doc__ 等信息,使用 functools.wraps 可以解决:
from functools import wraps
def logged(func): @wraps(func) def wrapper(*args, **kwargs): print(f"调用 {func.__name__}") return func(*args, **kwargs) return wrapper
|
实际应用场景
- 缓存:
functools.lru_cache 自动缓存函数结果
- 权限校验:在 Web 框架中校验登录态
- 日志埋点:统一记录函数调用与耗时
- 重试机制:网络请求失败自动重试
装饰器让代码复用变得极其简洁,是 Python 进阶路上必须掌握的核心技巧。