为何未显式调用被装饰函数,部分装饰器代码却自动执行?
为何未显式调用被装饰函数,部分装饰器代码却自动执行?
嗨,这个问题其实是对Python装饰器执行时机的小误解,我来给你拆解清楚~
首先得明白:Python的装饰器语法@xxx可不是单纯的“标记”,它背后是Python在模块加载阶段自动帮你完成了一系列调用操作,咱们结合你的两段代码分别来看:
第一段代码的执行逻辑
先把你的代码贴出来方便对照:
def decorator(*args, **kwargs): print("Inside decorator") def inner(func): # code functionality here print("Inside inner function") print("I like", kwargs['like']) func() # returning inner function return inner @decorator(like = "geeksforgeeks") def my_func(): print("Inside actual function")
当Python加载这个模块时,会按顺序执行到@decorator(like="geeksforgeeks")这一行,这时候会发生两件事:
- 先调用
decorator(like="geeksforgeeks"):这时候decorator函数里的print("Inside decorator")会立刻执行,然后返回内部定义的inner函数。 - 用返回的
inner函数装饰my_func:Python会把my_func作为参数传给inner,这时候inner函数里的代码会全部执行——包括打印"Inside inner function"、打印"I like geeksforgeeks",还有直接调用func()(也就是my_func),所以最后会打印"Inside actual function"。
简单说:第一段代码里的inner函数在接收目标函数后,直接主动调用了它,所以你不用自己写my_func(),Python在装饰阶段就帮你执行了。
第二段代码的执行逻辑
再看第二段代码:
def decorator(*args,**kwargs): def inner1(func): def inner2(): print(args[0]) print(kwargs['like']) print("nitin") func() return inner2 return inner1 @decorator("sourav",like="priyansh") def printpankaj(): print("pankaj")
这段是三层嵌套的装饰器,执行流程是:
- 先调用
decorator("sourav",like="priyansh"),返回inner1函数(这一步没有任何打印,因为decorator里只有函数定义)。 - Python把
printpankaj传给inner1,inner1定义了inner2并返回它(这一步也没有执行inner2里的代码,只是定义并返回)。
这时候被装饰后的printpankaj其实已经变成了inner2函数,但只有当你显式调用printpankaj()时,才会触发inner2的执行,那些打印语句和func()(也就是原printpankaj)才会运行起来。所以你现在没看到任何输出,就是因为没触发这最后一步调用。
核心总结
- 带参数的装饰器
@decorator(...),第一步必然是执行decorator(...)获取真正的装饰器函数,这部分代码会在模块加载时自动运行。 - 装饰器内部是否会自动执行目标函数,完全取决于装饰器的写法:如果装饰器的内层函数(比如第一段的
inner)在接收目标函数后直接调用了它,那模块加载时就会自动执行;如果内层函数只是包裹目标函数(比如第二段的inner2),那必须显式调用被装饰后的函数才会触发执行。
备注:内容来源于stack exchange,提问作者pankaj kushwaha
相关产品推荐
相关产品推荐

