You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python装饰器与包装函数执行顺序解析:代码运行序列困惑

Python装饰器与包装函数执行顺序解析

先看你写的测试代码:

def DecoratorFun(func):
    # first wrapper function defined in a decorator is returned
    print("DecoratorFun is called")

    def WrapperFun1():
        print("In DecoratorFun and WrapperFun1")
        func()
        print("after WrapperFun1")
    return WrapperFun1

    # WrapperFun2 is not called or returned (ignored and lost ?)
    def WrapperFun2():
        print("In DecoratorFun and WrapperFun2")
        func()
        print("after WrapperFun2")
    return WrapperFun2

@DecoratorFun
def TestFun():
    print("In Test Function")

print("\n")
print(DecoratorFun(TestFun)())

运行输出:

DecoratorFun is called
In DecoratorFun and WrapperFun1
In DecoratorFun and WrapperFun1
In Test Function
after WrapperFun1
after WrapperFun1
None

你困惑的重复执行序列,本质是两次嵌套调用了WrapperFun1,下面一步步拆解执行逻辑:

1. 装饰器语法糖的初始化执行

当你用@DecoratorFun修饰TestFun时,Python会自动执行DecoratorFun(原始TestFun):

  • 打印DecoratorFun is called(这是输出的第一行)
  • 定义WrapperFun1和WrapperFun2,但由于return WrapperFun1在WrapperFun2之前,WrapperFun2的定义和后续代码永远不会被执行,直接被忽略
  • 将TestFun的指向替换为返回的WrapperFun1——此时全局的TestFun已经不是你最初定义的那个打印In Test Function的函数了,而是WrapperFun1

2. 关键语句print(DecoratorFun(TestFun)())的执行

这一行是触发重复输出的核心,拆成三步看:

2.1 调用DecoratorFun(TestFun)

这里传入的TestFun已经是第一步中被替换后的WrapperFun1,所以:

  • 再次打印DecoratorFun is called(你的输出里可能漏了这一行,不过不影响核心逻辑)
  • 再次定义WrapperFun1并返回它

2.2 调用返回的WrapperFun1()

此时执行这个新的WrapperFun1:

  • 打印In DecoratorFun and WrapperFun1(这是重复序列的第一行)
  • 调用func()——这里的func是传入的TestFun,也就是第一步中被替换后的旧WrapperFun1

2.3 调用旧WrapperFun1()

此时执行旧的WrapperFun1:

  • 打印In DecoratorFun and WrapperFun1(重复序列的第二行)
  • 调用func()——这里的func是最开始的原始TestFun
    • 打印In Test Function
  • 打印after WrapperFun1(重复序列的第四行)

2.4 回到新WrapperFun1()的执行

执行完旧WrapperFun1后,回到新WrapperFun1:

  • 打印after WrapperFun1(重复序列的第五行)

3. 最后打印返回值

由于WrapperFun1没有定义返回值,默认返回None,所以最后一行输出None

另外补充:你代码里的WrapperFun2确实永远不会被执行,因为return WrapperFun1语句会直接跳出DecoratorFun函数,后面的代码都不会运行。

内容的提问来源于stack exchange,提问作者Giridhar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 22:27:03