首先講到多層裝飾器的時候老師都會這麼說:
多個裝飾器的呼叫順序是自下往上,但是執行時的執行順序是自上往下!!!
但是呢,我們並不知道為什麼是這樣的,於是抱著求真務實,積極努力,奮發圖強的精神。我反覆試了**,設定斷點,看看內部到底發生了啥
先把測試用的**放上來
def
decorator_a
(func):
print('進入了 a')
definner_a
(*args, **kwargs):
print('進入了 inner_a')
return func(*args, **kwargs)
return inner_a
defdecorator_b
(func):
print('進入了 b')
definner_b
(*args, **kwargs):
print('進入了 inner_b')
return func(*args, **kwargs)
return inner_b
@decorator_b
@decorator_a
deff
(x):
print( 'get in f')
return x * 2
f1 = f
print(f1(1))
結果如下:
進入了 a
進入了 b
進入了 inner_b
進入了 inner_a
get in f
2
剛開始接觸的時候就比較好奇,雖然知道被裝飾的函式最後執行,而且呼叫的順序從下往上,可為什麼進入a
之後並沒有進入inner_a
,反而是進入了b
。
網上找了好久,最後發現,當我們對函式進行修飾的時候其實是對函式進行這樣的操作:
裝飾器寫法:
@decorator_b
@decorator_a
deff
(x):
print( 'get in f')
return x * 2
fc = f
fc(1)
等價於以下寫法:
def
f(x):
print( 'get in f')
return x * 2
f1 = decorator_a(f)
f2 = decorator_b(f1)
fc = f2
fc(1)
我們此時如果執行就會出現:
進入了 a
進入了 b
我們一步步來看
當我們使用裝飾器時,首先是第乙個裝飾器decorator_a(f)
呼叫了f
函式 ,傳入的是乙個函式,返回的是inner_a
,也是乙個函式。這時候就要問了,為什麼我返回函式後沒有把inner_a
裡面的內容一起返回出來。
因為!!!我們這裡返回的函式inner_a
給了f1
,此時的f1
是乙個函式.
f1
只是呼叫了decorator_a()
這個函式,但是他本身並沒有被呼叫,所以他不會將內部的功能使用出來。這就好比你爹給你取了名字,但是你爹此時並沒有喊你過去,那麼你就不會主動去找爹問有什麼事要做
如果我們這時候加上這句**:(這句話就像你爹在喊你「二狗,過來幫個忙」)
f1 = decorator_a(f)
fa = f1(2) #加在這兒
這才是呼叫了函式,這樣我們執行時才會進入inner_a
進入了 a
進入了 inner_a
get in f
我們繼續看(回到我這句話沒加之前)
f1 = decorator_a(f)
f2 = decorator_b(f1)
fc = f2
fc(1)
我們f1
呼叫了decorator_a(f),然後就會一步步執行,首先列印了個
進入了 a
然後我們用f2
呼叫了decorator_b(f1)
這不就是進入了decorator_b
裡面,所以接著列印了
進入了 b
但是f1,f2
此時都還沒有被呼叫(爹都沒喊他們),下面先是由他爹給他們取名字(引用)
fc = f2
接著他爹喊人了(「二狗你過來(fc你過來)」)
fc(1)
因為喊的是f2
於是先執行f2
裡的東西
進入了 inner_b
進入後,我們的inner_b
後它是有返回值的,它返回的是啥? 是它之前由f1
傳進來的inner_a
這下由f1
傳進f2
的inner_a
也就被執行了,所以列印了
進入了 inner_a
做完這一步後,我們的inner_a
也是有返回值的
return func(*args, **kwargs)
返回了當年傳進來的引數,傳進來的引數不就是函式f
嘛,就是下面這個
def
f(x):
print( 'get in f')
return x * 2
於是就去呼叫f
,同時我們還給它傳了個引數fc(1)
,之前傳的1
所以他就先列印了
get in f
然後又返回了乙個值,就是1*2
Python 多層裝飾器
python 的裝飾器能夠在不破壞函式原本結構的基礎上,對函式的功能進行補充。當我們需要對乙個函式補充不同的功能,可能需要用到多層的裝飾器。在我的使用過程中,遇到了兩種裝飾器層疊的情況,這裡把這兩種情況寫下來,作為踩坑記錄。def a func defdecorated c fune defdeco...
python 多層裝飾器
25 多層裝飾器 1 原理 執行順序從上往下,2和 3組成乙個函式假設為nf1,1和nf1組成乙個函式nnf1 f1成為ck ty of us的inner函式即nf1。nf1成為check login的inner函式即nnf1。詳細參照alex的多層裝飾器講解。1 check login 2 ck ...
多層裝飾器例子
def outter1 func1 print 載入了outter1 print res1 func1 args,kwargs return res1 return defoutter2 func2 print 載入了outter2 print res2 func2 return res2 retu...