总结
多个装饰器的应用顺序是自下而上、调用顺序是自上而下。
即:
- 装饰器的应用顺序:从下往上(先执行最下方的装饰器函数,包装上一层)
- 装饰器的执行顺序:从上往下(先执行最上层的装饰逻辑)
一、装饰器嵌套结构图解
@decorator_a
@decorator_b
def func():pass
等价于:
func = decorator_a(decorator_b(func))
即先应用 decorator_b
,再被 decorator_a
包装。
二、示例验证执行顺序
from functools import wrapsdef deco_a(func):@wraps(func)def wrapper(*args, **kwargs):print("进入 A")result = func(*args, **kwargs)print("离开 A")return resultreturn wrapperdef deco_b(func):@wraps(func)def wrapper(*args, **kwargs):print("进入 B")result = func(*args, **kwargs)print("离开 B")return resultreturn wrapper@deco_a
@deco_b
def hello():print("Hello World")hello()
输出结果:
进入 A
进入 B
Hello World
离开 B
离开 A
三、总结执行流程
-
装饰器装配阶段(解释器加载):
hello = deco_a(deco_b(hello))
- 顺序是从下往上装配(
B -> A
)
-
调用阶段:
- 实际执行顺序是:A → B → 原函数 → B → A
- 即最外层先进入,最内层先调用原函数
四、建议使用顺序
- 权限控制类装饰器:写在最上面,最先执行
- 日志记录、缓存类装饰器:通常写在中间
- 响应包装类装饰器(如标准返回结构):可写最底层
@permission_required
@log_operation
@format_response
def get_data():...
五、类视图方法的装饰器注意事项(如 Django)
@method_decorator
应用于类视图方法时,顺序同样遵循“自下而上包装,自上而下执行”原则。- Django 中 CBV 的装饰器也建议优先写权限、再写日志、最后写响应处理。