您好,登錄后才能下訂單哦!
裝飾器原理:
????裝飾器是為了在不改變?cè)瘮?shù)的功能的同時(shí)給原函數(shù)增加一些新功能的函數(shù)叫做裝飾器。
首先說一下簡(jiǎn)單的裝飾器原理
def?aa(): ????print('我就是一個(gè)簡(jiǎn)單的函數(shù)')
我們?nèi)绻俨桓淖冞@個(gè)函數(shù)的基礎(chǔ)上添加一個(gè)新功能該怎么做?
我們只需要添加一個(gè)新函數(shù)來調(diào)用這個(gè)函數(shù),然后在形函數(shù)上添加新功能就好了,例如
def?decorate(fn): ????def?inner(): ????????print('這個(gè)是新加功能') ????????return?fn ????return?inner() def?aa(): ????print('我就是一個(gè)簡(jiǎn)單的函數(shù)') aa?=?decorate(aa) aa()
輸出結(jié)果為:
這個(gè)是新加功能 我就是一個(gè)簡(jiǎn)單的函數(shù)
下面就看看更詳細(xì)一點(diǎn)的裝飾器
直接上代碼,查看結(jié)果
def?decorate(func): ????def?inner(a,b): ????????print('3?給函數(shù)添加一個(gè)求和的輸出?{}?{}'.format(a,b)) ????????print('4?我要打印func函數(shù)',?func) ????????result?=?func(a,b) ????????print('6?我要打印add函數(shù)',?add) ????????print('7?我要打印func函數(shù)',?func) ????????print('8?我要打印inner函數(shù)',?inner) ????????return?result ????print('2?我要打印decorate函數(shù)',decorate) ????return?inner @decorate def?add(a,b): ????print('5?我要打印add函數(shù)',?add) ????return?a+b print('1?我應(yīng)該是首個(gè)打印的') print('9?這是函數(shù)輸出的結(jié)果',add(1,2))
輸出結(jié)果為:
2?我要打印decorate函數(shù)?decorate 1?我應(yīng)該是首個(gè)打印的 3?給函數(shù)添加一個(gè)求和的輸出?1?2 4?我要打印func函數(shù)?add 5?我要打印add函數(shù)?inner 6?我要打印add函數(shù)?inner 7?我要打印func函數(shù)?add 8?我要打印inner函數(shù)?inner 2?我要打印decorate函數(shù)?decorate 9?這是函數(shù)輸出的結(jié)果?3
過程分析
由上面的輸出,我們可以看得出來,裝飾器的執(zhí)行順序是,213456789;
那是因?yàn)锧裝飾器函數(shù),然后相當(dāng)于把函數(shù)add傳給了裝飾器,從而變成了add = decorate(add),這里調(diào)用了decorate函數(shù)把函數(shù)add傳到了
裝飾器內(nèi)部,然后就打印了第二步,由于沒有后續(xù)的調(diào)用,程序就在這里在inner處停滯等待被調(diào)用,而inner的實(shí)際指針已經(jīng)指向了add函數(shù)
所以打我們打印func的時(shí)候輸出的是add函數(shù),并沒有帶locals,這里就不屬于decorate的內(nèi)部函數(shù),而我們裝飾器下面的add函數(shù)卻已經(jīng)成
為了inner的內(nèi)部函數(shù)了,接下來的邏輯就是正常的函數(shù)執(zhí)行邏輯了
#裝飾器過程
@decorare+add --》decorate--》inner--》result=func 即 result=add--》
#調(diào)用過程
(新add)add(1,2)--》result(1,2)--》(被裝飾函數(shù)add)add(1,2)--》輸出結(jié)果
但是經(jīng)過了裝飾器這兩個(gè)add只是同名而已
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。