七、实际应用场景大全
7.1 计时装饰器
import timedef timer(func): @functools.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
7.2 缓存(Memoization)
def cache(func): memo = {} @functools.wraps(func) def wrapper(*args): if args in memo: return memo[args] result = func(*args) memo[args] = result return result return wrapper@cachedef fibonacci(n): if n < 2: return n return fibonacci(n-1) + fibonacci(n-2)
注意:对于可变参数需要转成不可变类型(如 tuple(args))。Python 3.9+ 可直接用 functools.lru_cache。
7.3 权限校验(Web 框架常见)
def require_login(func): @functools.wraps(func) def wrapper(request, *args, **kwargs): if not request.user.is_authenticated: raise PermissionError("请先登录") return func(request, *args, **kwargs) return wrapper@require_logindef dashboard(request): return "欢迎回来"
7.4 异常重试(带退避)
def retry_with_backoff(max_retries=3, base_delay=1): def decorator(func): @functools.wraps(func) def wrapper(*args, **kwargs): for i in range(max_retries): try: return func(*args, **kwargs) except Exception as e: if i == max_retries - 1: raise delay = base_delay * (2 ** i) # 指数退避 time.sleep(delay) return None return wrapper return decorator
7.5 单例模式
def singleton(cls): instances = {} @functools.wraps(cls) def get_instance(*args, **kwargs): if cls not in instances: instances[cls] = cls(*args, **kwargs) return instances[cls] return get_instance@singletonclass DatabaseConnection: def __init__(self): print("创建数据库连接")
7.6 类型检查(简单版)
def type_check(**types): def decorator(func): @functools.wraps(func) def wrapper(*args, **kwargs): # 绑定参数名和值(简化,实际需用 inspect) for arg_name, expected_type in types.items(): value = kwargs.get(arg_name) if value is not None and not isinstance(value, expected_type): raise TypeError(f"{arg_name} 应为 {expected_type},实际是 {type(value)}") return func(*args, **kwargs) return wrapper return decorator@type_check(name=str, age=int)def greet(name, age): print(f"{name} 今年 {age} 岁")