Python多个装饰器的执行顺序

编程入门 行业动态 更新时间:2024-10-10 08:18:13

Python<a href=https://www.elefans.com/category/jswz/34/1771377.html style=多个装饰器的执行顺序"/>

Python多个装饰器的执行顺序

看了好多相关文章,也有些有错误,还是自己记录一下吧.

def decrator_a(func):print("enter decrator_a")def inner_a(*args,**kwargs):print("enter inner_a")ret = func(*args,**kwargs)print("leaving  inner_a")return retprint("leaving decrator_a")return inner_adef decrator_b(func):print("enter decrator_b")def inner_b(*args,**kwargs):print("enter inner_b")ret = func(*args,**kwargs)print("leaving  inner_b")return retprint("leaving decrator_b")return inner_b@decrator_a
@decrator_b 
def f(*args,**kwargs):print("==f==")
#相当于decrator_a(decrator_b(f))
f()

执行结果为:

>>> 
RESTART: C:/Users/Administrator/AppData/Local/Programs/Python/Python36/tests/decrator_test.py 
enter decrator_b
leaving decrator_b
enter decrator_a
leaving decrator_a
enter inner_a
enter inner_b
==f==
leaving  inner_b
leaving  inner_a

解释一下顺序
明确两点 一是装饰器的执行顺序从下往上,函数调用时从上往下. 二是装饰器函数在被装饰函数定义好后立即执行
一好理解,二的意思就是说即使f没有执行,上面的装饰器函数还是会执行(可以把f()删掉直接运行一下试试)

首先例子中的装饰器顺序相当于decrator_a(decrator_b(f)), 而decrator_b(f)返回的就是一个函数,如此循环的话,在多个装饰器也可以看成只有最外层的一个.另外函数f经过装饰器装饰后,函数f = decrator_a(decrator_b(f)),
然后根据装饰器的特点,执行顺序从近到远,或者说由下而上,先执行decrator_b(f),看代码,先打印一个①"enter decrator_b",然后定义了一个函数inner_b, 返回值为f的执行结果,然而,这个inner_b这个函数并没有被调用,所以相当于一个pass,可以暂时跳过,然后打印一个②"leving decrator_b", 并返回一个函数inner_b,这时候返回这个函数,返回的是函数,而不是函数的执行结果,所以此时inner_b函数还是没有执行,只是 被返回了
这时就变成了decrator_a(inner_b),跟据代码,也是先打印③"enter decrator_a", 然后也是定义一个函数inner_a,同样当成是pass,然后打印④"leaving decrator_a", 然后返回inner_a,
如果没有f()这行,会返回这个结果,会打印四行,分别是
enter decrator_b
leaving decrator_b
enter decrator_a
leaving decrator_a
加上f()这行之后,就开始执行函数了
因为此时函数f是经过装饰器装饰过的了, f = inner_a, f() = inner_a()
然后再来看函数inner_a, 相当于

def inner_a(*args,**kwargs):print("enter inner_a")ret = inner_b(*args,**kwargs)print("enter inner_a")return ret

所以这时候打印一个"enter inner_a", 然后执行inner_b并把结果赋值给变量ret, inner_b执行时打印一句"enter inner_b", 然后开始执行函数f,这个函数f是还没有经过装饰器装饰的函数,(相当于 a = 1 a = a +1 ,a = a +1 中等号后面的a还是原来的a=1),所以应该打印一行⑤" =f=", 这时函数f执行完了,返回上一级的inner_b中,继续执行,打印一行⑥"leaving inner_b", 然后返回inner_b中的ret,因为函数f没有返回值,所以返回None, 再往上一级返回inner_a中,ret = None,打印一行⑦"leaving inner_a",最后返回ret,也就是None, 这里并没有打印返回结果,所以None不会在打印结果中出现.

更多推荐

Python多个装饰器的执行顺序

本文发布于:2024-02-07 02:11:10,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1752675.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:多个   顺序   Python

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!