装饰器的执行顺序图解
今天学了装饰器,有些懵逼,主要是其执行顺序分析起来有些复杂,就好比我,现在就来理下装饰器的执行顺序,只讨论 函数装饰器,类装饰器还没学到。
先看一个两层装饰器:
def fir(func2): print(2) def warp2(*args,**kwargs): print(3) func2(*args,**kwargs) print(6) return warp2 def sec(func1): print(1) def warp1(*args,**kwargs): print(4) func1(*args,**kwargs) print(5) return warp1 @fir @sec def aa(c): print(c) aa('最里边')
执行结果:
我的理解,装饰器就是把函数层层装饰。藏到最里面,调用的话从最外边找。
你可以把装饰器比喻成炼丹炉,被装饰的函数好比是猴子,我们的任务就是救出炼丹炉的猴子。
装饰器就是打包后塞给另一个装饰器,被装饰的函数在最里面,执行顺序,你先要爬到最高的装饰器上面往下跳
sec装饰器里面打包了aa函数,返回值warp直接扔给了上一层的装饰器fir,fir装饰器接受到扔来的打包装饰器引用给了fun2,所以
现在的fun2引用的是sec装饰器的包裹。要想获得数据就需要打开sec这个包裹才能救出猴子。
这里aa函数引用到了func1,往下走代码,遇到print(1)可以执行,则执行。加载warp1进入内存return返回warp1
这里@fir和@sec你可以看作是
@fir = aa = fir(aa)
@sec = aa = sec(aa)
这里fir的aa和sec里的aa有些区别,你可以看成
aa = fir(warp1)
warp1 = sec(aa)
fir(aa)指的是aa函数 ,最上面的aa则指的是aa函数的调用,最下面调用的aa(c)
aa(c) 就是被装饰的函数的最终执行语句
fir拿到warp1的数据来到fir装饰器里开始执行,遇到print(2)执行。往下走,返回warp2,到现在所有的数据都打包好了,该执行的都执行了,然后就去找老君要钥匙吧
aa = fir(warp1)
执行语句aa()相当于开启炼丹炉的钥匙,可以开启打包好的函数
fri(warp1)拿到钥匙就可以进入warp2函数了。
遇到print(3)执行,
遇到了finc2()执行函数,那我们就可以进入到func2,别忘了func2可是通往sec装饰器的大门,猴子就是被关在那里的。
我们通过 func2 ----warp1 来到sec,新的一关开始了
刚开始就遇到print(4),直接消灭了。找到了func1函数,猴子就被关在这个函数里。执行aa()函数
至此,任务完成。成功救到了猴子,接下来的任务就是离开炼丹炉了。
返回又遇到了print(5)顺手消灭了。
通过warp1 ------func2 离开sec装饰器,来到fir装饰器
遇到print(6)消灭
通过warp2 ------返回到外面的世界。
所以我们把猴子交给aa()函数,游戏通关
至此程序也完结了。
分析结束。
程序菜单
消灭怪兽
print(1)-------print(2)--------print(3)---------print(4)---------print(5)---------print(6)
完结撒花。
所以说装饰器就是一个先顺着装饰器找到最外层的装饰器,把所有的程序打包好,在去函数执行那里去取进入封装函数的钥匙
一路向下找到被装饰的函数执行,最后在顺着函数爬出来的过程。结合其他博客的装饰器的内容,装饰器的就不难理解了。
最后说一句,这怎么这么像fc游戏!!