Python装饰器高级应用:5个实战案例提升代码优雅度
1. 性能分析装饰器
自动测量函数执行时间:
import time
from functools import wraps
def timer(func):
@wraps(func)
def wrapper(*args, **kwargs):
start = time.perf_counter()
result = func(*args, **kwargs)
end = time.perf_counter()
print(f"{func.__name__} 执行时间: {end - start:.4f}秒")
return result
return wrapper
@timer
def heavy_computation(n):
return sum(i * i for i in range(n))
heavy_computation(10**6)
2. 缓存装饰器
实现函数结果缓存:
from functools import lru_cache
@lru_cache(maxsize=128)
def fibonacci(n):
if n < 2:
return n
return fibonacci(n-1) + fibonacci(n-2)
# 第一次计算会递归调用
print(fibonacci(50))
# 第二次直接从缓存读取
print(fibonacci(50))
3. 权限验证装饰器
实现简单的权限控制:
def requires_role(role):
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
user = kwargs.get('user')
if not user or user.role != role:
raise PermissionError("权限不足")
return func(*args, **kwargs)
return wrapper
return decorator
@requires_role('admin')
def delete_user(user_id, user=None):
print(f"删除用户 {user_id}")
delete_user(123, user=User(role='admin'))
4. 重试机制装饰器
自动处理失败重试:
import random
from time import sleep
def retry(max_attempts=3, delay=1):
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
attempts = 0
while attempts < max_attempts:
try:
return func(*args, **kwargs)
except Exception as e:
attempts += 1
print(f"尝试 {attempts} 失败: {e}")
if attempts < max_attempts:
sleep(delay)
raise Exception(f"所有 {max_attempts} 次尝试均失败")
return wrapper
return decorator
@retry(max_attempts=5, delay=2)
def unreliable_api_call():
if random.random() < 0.8:
raise ConnectionError("API调用失败")
return "成功"
装饰器类型 | 主要用途 | 适用场景 |
---|---|---|
函数装饰器 | 修改或增强函数行为 | 日志、计时、缓存等 |
类装饰器 | 修改或增强类定义 | 单例模式、属性检查等 |
带参数装饰器 | 可配置的装饰行为 | 权限控制、重试机制等 |
5. 类方法装饰器
使用类实现装饰器:
class Deprecated:
def __init__(self, message="此方法已弃用"):
self.message = message
def __call__(self, func):
@wraps(func)
def wrapper(*args, **kwargs):
print(f"警告: {self.message}")
return func(*args, **kwargs)
return wrapper
@Deprecated("请使用 new_method() 代替")
def old_method():
print("旧方法逻辑")
old_method()
通过合理使用装饰器,可以显著提升Python代码的质量和可维护性,是Python开发者必须掌握的高级技巧。