裝飾器執行的原理 順序

2021-10-24 07:16:21 字數 2889 閱讀 8912

多個裝飾器裝飾函式時的執行過程

多個裝飾器裝飾函式時,離函式近的裝飾器先進行裝飾,下面的裝飾器先裝飾完後將整個裝飾結果給第乙個裝飾器進行裝飾

即:封裝時自內而外(自下而上),執行時自外而內(自上而下)

以**為例:

##定義裝飾器

defcheck

(func)

:print

("驗證許可權"

)def

inner

(identify)

: func(identify)

return inner

###裝飾裝飾器

@check

deff1

(user_id)

:if user_id==

"root"

:print

("允許root使用者操作"

)else

:print

(f"不允許

使用者操作"

)f1(

"root"

)

流程如下:

這裡的裝飾器函式是check,check函式接收乙個引數func,其實就是接收乙個函式的名字,check函式內部又定義了乙個函式inner,在inner函式中增加許可權校驗,並在驗證完許可權後呼叫傳進來的引數func,同時check的返回值為內部函式inner,其實就是乙個閉包函式。

在函式f1上增加@check,其實就是給f1函式額外的增加了許可權驗證的輸出語句。當python直譯器執行到這條語句的時候,會去呼叫check函式,同時將被裝飾的函式名作為引數傳入(此時為f1),根據閉包分析,在執行check函式的時候,返回值是inner函式,同時把返回值inner賦值給f1函式(這裡其實傳遞的是函式的引用),此時的f1已經不是未加裝飾時的f1了,即f1函式已經改變了,不再是原來的內容了,而是指向了check.inner函式的位址。

在呼叫f1(「root」)的時候,其實呼叫的是check.inner函式,那麼此時就會先執行許可權驗證,然後再呼叫原來的f1(「root」),該處的f1就是通過裝飾傳進來的引數f1。

從而,就完成了對函式f1的裝飾,實現了許可權驗證功能。

#####定義第乙個裝飾器

deffirst

(fun)

:print

('----第乙個裝飾器封裝----'

)def

inner1

(*args,

**kwargs)

:print

('----第乙個裝飾器執行----'

)return

'《第乙個》'

+ fun(

*args,

**kwargs)+'

return inner1

#####定義第二個裝飾器

defsecond

(fun)

:print

('----第二個裝飾器封裝----'

)def

inner2

(*args,

**kwargs)

:print

('----第二個裝飾器執行----'

)return

'《第二個》'

+ fun(

*args,

**kwargs)+'

return inner2

#####裝飾器去裝飾函式

@first

@second

deftest

(a,b)

:print

('----被裝飾的函式開始執行----'

)return

f'hello python decorator,+=

'print

("開始呼叫函式test"

)ret = test(1,

3)print

(ret)

執行結果為:

可以看到,多個裝飾器去裝飾同乙個函式的時候,最裡面的裝飾器是最開始進行裝飾的。

執行步驟:

用@second裝飾器去對函式test進行裝飾,因此會先去執行second函式,因為此時還沒有呼叫test函式,所以不會執行second函式裡面的inner2函式,所以就輸出了「----第二個裝飾器封裝----「語句,並且返回inner2的引用,所以此時就是second(test)函式。

該函式又被@first函式裝飾,因此就先去執行first函式,因為此時還沒有呼叫test函式,所以不會執行first函式裡面的inner1函式,所以就輸出了「----第乙個裝飾器封裝----「語句,並且返回inner1的引用,所以此時就是first(second(test))函式。

所以前1,2步就是進行函式的封裝。

函式裝飾完畢之後,就執行到print(「開始呼叫函式test」)語句了,輸出「開始呼叫函式test」

呼叫函式test(1,3),此時的函式不再是原來的test了,而是經過裝飾器裝飾的函式了,此時的函式是first(second(test))。因為返回的是inner1函式的引用,所以會先去執行inner1函式,輸出「第乙個裝飾器執行「,然後返回《第乙個》+inner2的引用+接著去執行inner2的引用,所以就會輸出語句「第二個裝飾器執行」,並且返回《第二個》+test的引用+接著去執行test的引用,此時就真正的呼叫函式test了,所以會輸出語句「----被裝飾的函式開始執行----」

然後返回hello python decorator,1+3=4,再將前面返回的內容一層層組合,所以最終的返回值是《第乙個》《第二個》hello python decorator,1+3=4第二個》第乙個》

Python 裝飾器執行順序

nisen的 python 裝飾器執行順序迷思 原址 裝飾器是python用於封裝函式或 的工具,網上可以搜到很多文章可以學習,我在這裡要討論的是多個裝飾器執行順序的乙個迷思。大部分涉及多個裝飾器裝飾的函式呼叫順序時都會說明它們是自上而下的,比如下面這個例子 def decorator a func...

函式裝飾器執行順序

今天學了裝飾器,有些懵逼,主要是其執行順序分析起來有些複雜,就好比我,現在就來理下裝飾器的執行順序,只討論 函式裝飾器,類裝飾器還沒學到。先看乙個兩層裝飾器 def fir func2 print 2 def warp2 args,kwargs print 3 func2 args,kwargs p...

python裝飾器執行順序

python 裝飾器 1 2層裝飾器 def decorator func todo def args,kwargs todo func args,kwargs todo todo 3層裝飾器 def decorator3 a 0 b 0 todo def func todo def args,kw...