Python - 裝飾器 & 閉包(針對初學者)
阿新 • • 發佈:2019-03-21
閉包 附加 代碼 位置 定義 class str 分享圖片 參數
一、裝飾器
本身就是函數,都是用def語法來定義的,為其他函數添加附加功能。
二、應用場景
假設目前編寫的函數已經上線運行了,某一天,產品有個需求,要在這個裏面新增一個功能,那怎麽去做這個事?最簡單的就是:重新編碼。但是問題是程序已經運行了,修改程序源碼,會有風險發生。
所以說,我要新增一個功能,不能夠修改函數的源代碼,且不改變原函數的調用方式,這個時候裝飾器就出現了
閉包
要了解裝飾器首先要知道什麽是閉包
總結起來就是:
1、外層函數返回了內存函數的引用
2、內層函數引用了外層函數的參數
1 def out(num): #外層函數2 print(‘1‘)
3 def inner(): #內層函數
4 print(num)
5 print(‘5‘)
6 print(‘2‘)
7 return inner #返回了內層函數的引用
8
9 res = out(4)
10 res()
這就是閉包,那麽閉包是怎麽執行的呢
1 2 4 5
當調用out() 的時候,此時執行外層函數,輸出1,輸出2 ,註意:當程序執行到第3行時,只是在此聲明了一個函數,並沒有做任何事情,此時res接收了out的返回值(inner函數的引用)
當調用res() 的時候,此時相當於調用inner函數,輸出4,輸出5,執行完畢
執行內部函數的時候,外層函數的變量並沒有被銷毀,可以一直被調用。
def out(num): print(‘1‘) def inner(num_inner): print(num) print(num_inner) print(‘2‘) return inner res = out(4) res(11) res(22) res(33) res(44)
此時輸出結果為
1 2 4 11 4 22 4 33 4 44
此種應用,雖然編寫函數的時候會稍微麻煩點,但是可以反復調用,不會被釋放,傳參數的時候也可以簡化
裝飾器
1、只是在原來的函數基礎上增加新的函數,達到在執行原來的函數之前或者之後執行新添加的功能
2、不改變原函數的調用方式,原來調用哪個函數現在還調用哪個函數
示例一:
def out1(func): #此函數相當於拓展函數 print(‘外層開始執行‘) def inner1(): print(‘內層開始執行‘) func() print(‘外層執行完畢‘) return inner1
@out1 def ma(): #此函數相當於原來的函數 print(‘這是一個主函數‘) ma() #調用方式依舊是原來的調用
輸出結果
外層開始執行
外層執行完畢
內層開始執行
這是一個主函數
示例二:
def out1(canshu): print(‘外層開始執行‘) def inner1(): print(‘內層開始執行‘) canshu() print(‘外層執行完畢‘) return inner1 # @out1 def ma(): print(‘這是一個主函數‘) ma = out1(ma) ma()
輸出結果
外層開始執行
外層執行完畢
內層開始執行
這是一個主函數
可以看到上面兩種方式實現了同樣的功能(示例一屬於閉包函數裝飾了原來的函數)
可以看出
ma = out1(ma)
ma()
只是被 語法糖 @out1 替換掉了
在函數ma上面加上了@out1,就相當於 out1(ma)
當程序執行到@定義的位置,就會自動執行閉包體的外層函數,當執行到原函數調用時,會自動執行閉包體的內層函數
下面附上詳細圖片
Python - 裝飾器 & 閉包(針對初學者)