python的装饰器模式

0 阅读2分钟

本质

装饰器是一个接受函数作为参数、返回新函数的可调用对象(通常是闭包)。它用于在不修改原函数代码的情况下,增加额外功能。

适用场景

1. 日志记录

def log(func):
    def wrapper(*args, **kwargs):
        print(f"Calling {func.__name__}")
        return func(*args, **kwargs)
    return wrapper

@log
def greet(name):
    print(f"Hello {name}")

2. 执行时间统计 / 性能分析

import time

def timer(func):
    def wrapper(*args, **kwargs):
        start = time.time()
        result = func(*args, **kwargs)
        print(f"{func.__name__} took {time.time()-start:.4f}s")
        return result
    return wrapper

@timer
def heavy_computation():
    time.sleep(1)

3. 权限校验 / 认证

def login_required(func):
    def wrapper(user, *args, **kwargs):
        if not user.get('is_authenticated'):
            raise PermissionError("请先登录")
        return func(user, *args, **kwargs)
    return wrapper

@login_required
def view_profile(user):
    print("查看个人资料")

4. 缓存 / 记忆化(Memoization)


@lru_cache(maxsize=128)
def fib(n):
    if n < 2:
        return n
    return fib(n-1) + fib(n-2)

5. 重试机制

    def decorator(func):
        def wrapper(*args, **kwargs):
            for i in range(times):
                try:
                    return func(*args, **kwargs)
                except Exception as e:
                    if i == times - 1:
                        raise e
                    print(f"Retry {i+1}")
        return wrapper
    return decorator

@retry(times=5)
def unstable_api_call():
    # 可能失败的操作
    pass

6. 事务管理(数据库)

    def wrapper(*args, **kwargs):
        try:
            result = func(*args, **kwargs)
            db.commit()
            return result
        except Exception:
            db.rollback()
            raise
    return wrapper

7. 路由注册(Web框架)


def route(path):
    def decorator(func):
        app[path] = func
        return func
    return decorator

@route('/home')
def home():
    return "Welcome home"

总结对比

特性闭包装饰器
核心函数+引用的外部变量接受函数返回函数的闭包
目的封装状态、延迟计算、函数工厂增强函数、横切关注点
何时用需要“带状态的函数”需要在不改源码情况下添加功能
典型计数器、惰性求值日志、计时、权限、缓存

简单判断:

  • 想创建一个“携带配置”的函数 → 闭包
  • 想为多个函数统一增加功能 → 装饰器