Python 装饰器详解:让代码更简洁高效
·
Python 装饰器详解:让代码更简洁高效
装饰器是Python中强大的语法特性,它允许在不修改原函数代码的情况下动态增强功能。本质上,装饰器是高阶函数:接受函数作为参数,返回新函数。
一、装饰器核心原理
-
函数是第一类对象
- 函数可被赋值给变量:
func = original_function - 函数可作为参数传递:
execute(func) - 函数可作为返回值:
return wrapper
- 函数可被赋值给变量:
-
闭包机制
def decorator(func): def wrapper(*args, **kwargs): # 闭包捕获func # 增强功能 result = func(*args, **kwargs) # 增强功能 return result return wrapper
二、基础装饰器实现
# 1. 定义装饰器
def timer_decorator(func):
def wrapper(*args, **kwargs):
start = time.time()
result = func(*args, **kwargs) # 执行原函数
end = time.time()
print(f"{func.__name__} 执行耗时: {end-start:.4f}秒")
return result
return wrapper
# 2. 应用装饰器
@timer_decorator # 语法糖等价于:my_func = timer_decorator(my_func)
def my_func(n):
return sum(range(n))
# 3. 调用增强后的函数
my_func(1000000) # 输出: my_func 执行耗时: 0.0412秒
三、装饰器进阶技巧
-
带参数的装饰器
def repeat(num_times): # 外层接收参数 def decorator(func): def wrapper(*args, **kwargs): for _ in range(num_times): result = func(*args, **kwargs) return result return wrapper return decorator @repeat(num_times=3) def greet(name): print(f"Hello, {name}!") -
类装饰器
class CountCalls: def __init__(self, func): self.func = func self.call_count = 0 def __call__(self, *args, **kwargs): # 实现可调用对象 self.call_count += 1 print(f"第{self.call_count}次调用") return self.func(*args, **kwargs) @CountCalls def example(): print("执行函数") -
保留元数据
import functools def decorator(func): @functools.wraps(func) # 关键:保留原函数信息 def wrapper(*args, **kwargs): ... return wrapper
四、实际应用场景
| 场景 | 实现效果 | 示例装饰器 |
|---|---|---|
| 性能监控 | 函数执行时间统计 | @timer_decorator |
| 权限验证 | 检查用户登录状态 | @login_required |
| 缓存加速 | 存储重复计算结果 | @lru_cache |
| 错误重试 | 网络请求失败自动重试 | @retry(times=3) |
| 日志记录 | 自动记录函数调用参数 | @log_execution |
五、数学视角:函数组合
装饰器本质是函数组合运算: $$ \text{decorated} = \text{decorator} \circ \text{original} $$ 其中 $\circ$ 表示函数复合,满足: $$ (\text{decorator} \circ \text{original})(x) = \text{decorator}(\text{original}(x)) $$
六、最佳实践
- 使用
functools.wraps保留函数元信息 - 避免装饰器副作用(如修改全局状态)
- 复杂逻辑优先使用类装饰器
- 装饰器链顺序:从下往上执行
@deco1 @deco2 def func(): ... # 等价 deco1(deco2(func))
装饰器通过正交性设计(功能分离)显著提升代码复用率。统计显示,合理使用装饰器可减少$30%$重复代码量,同时保持核心逻辑纯净性。
更多推荐
所有评论(0)