裝飾器原理:
裝飾器是爲了在不改變原函數的功能的同時給原函數增加一些新功能的函數叫做裝飾器。
首先說一下簡單的裝飾器原理
def aa(): print('我就是一個簡單的函數')
我們如果再不改變這個函數的基礎上添加一個新功能該怎麼做?
我們只需要添加一個新函數來調用這個函數,然後在形函數上添加新功能就好了,例如
def decorate(fn): def inner(): print('這個是新加功能') return fn return inner() def aa(): print('我就是一個簡單的函數') aa = decorate(aa) aa()
輸出結果爲:
這個是新加功能 我就是一個簡單的函數
下面就看看更詳細一點的裝飾器
直接上代碼,查看結果
def decorate(func): def inner(a,b): print('3 給函數添加一個求和的輸出 {} {}'.format(a,b)) print('4 我要打印func函數', func) result = func(a,b) print('6 我要打印add函數', add) print('7 我要打印func函數', func) print('8 我要打印inner函數', inner) return result print('2 我要打印decorate函數',decorate) return inner @decorate def add(a,b): print('5 我要打印add函數', add) return a+b print('1 我應該是首個打印的') print('9 這是函數輸出的結果',add(1,2))
輸出結果爲:
2 我要打印decorate函數 decorate 1 我應該是首個打印的 3 給函數添加一個求和的輸出 1 2 4 我要打印func函數 add 5 我要打印add函數 inner 6 我要打印add函數 inner 7 我要打印func函數 add 8 我要打印inner函數 inner 2 我要打印decorate函數 decorate 9 這是函數輸出的結果 3
過程分析
由上面的輸出,我們可以看得出來,裝飾器的執行順序是,213456789;
那是因爲@裝飾器函數,然後相當於把函數add傳給了裝飾器,從而變成了add = decorate(add),這裏調用了decorate函數把函數add傳到了
裝飾器內部,然後就打印了第二步,由於沒有後續的調用,程序就在這裏在inner處停滯等待被調用,而inner的實際指針已經指向了add函數
所以打我們打印func的時候輸出的是add函數,並沒有帶locals,這裏就不屬於decorate的內部函數,而我們裝飾器下面的add函數卻已經成
爲了inner的內部函數了,接下來的邏輯就是正常的函數執行邏輯了
#裝飾器過程
@decorare+add --》decorate--》inner--》result=func 即 result=add--》
#調用過程
(新add)add(1,2)--》result(1,2)--》(被裝飾函數add)add(1,2)--》輸出結果
但是經過了裝飾器這兩個add只是同名而已