多个装饰器叠加时按从下到上顺序应用,即@dec1@dec2@dec3等价于dec1(dec2(dec3(my_func))),执行时“由内向外”包装,各装饰器需正确透传参数并返回可调用对象。

多个装饰器叠加时,Python 按从下到上的顺序应用,即离函数定义最近的装饰器最先执行。
执行顺序:自下而上
写法上装饰器从上到下排列,但实际调用时是“由内向外”包装:
- @dec1 包裹的是 @dec2 处理后的函数
- @dec2 包裹的是 @dec3 处理后的函数
- 最底层是原始函数本身
例如:
@dec1
@dec2
@dec3
def my_func():
pass
等价于:my_func = dec1(dec2(dec3(my_func)))。
装饰器内部逻辑需支持嵌套调用
每个装饰器都应正确接收并返回一个可调用对象(通常是函数),确保能传递给下一个装饰器:
- 不要在装饰器里直接执行被装饰函数(除非有意立即触发)
- 务必在内层函数中调用
func(*args, **kwargs)并返回其结果(若需保留原函数行为) - 如果某个装饰器返回非函数类型(如
None),后续装饰器会报错
调试技巧:加打印或日志观察流程
为确认执行顺序,可在各装饰器中加入标识输出:
def dec1(func):
def wrapper(*args, **kwargs):
print("进入 dec1")
result = func(*args, **kwargs)
print("退出 dec1")
return result
return wrapper
def dec2(func):
def wrapper(*args, **kwargs):
print("进入 dec2")
result = func(*args, **kwargs)
print("退出 dec2")
return result
return wrapper
调用后输出顺序为:
进入 dec1 → 进入 dec2 → 原函数执行 → 退出 dec2 → 退出 dec1。
注意参数和返回值的透传
多个装饰器叠加时,中间任一环节若未正确转发 *args 和 **kwargs,会导致参数丢失或 TypeError:
- 内层 wrapper 必须使用
*args, **kwargs接收参数 - 调用原函数时也必须用
func(*args, **kwargs) - 若装饰器本身带参数(如
@dec(arg)),需多嵌套一层函数,但叠加规则不变










