Python必備基礎之閉包和裝飾器知識總結
一、閉包
1.1 三要素
必須有一個內嵌函數
內嵌函數必須引用外部函數中變量
外部函數返回值必須是內嵌函數
1.2 語法
# 語法 def 外部函數名(參數): 外部變量 def 內部函數名(參數): 使用外部變量 return 內部函數名 # 調用 變量 = 外部函數名(參數) 變量(參數)
舉個例子
def func01(): # 外部函數 a = 1 # 外部變量 print('外部變量:',a) def func02(num): #內部函數 print("調用內部函數後:",num + a). # 調用外部變量 # 調用 func01() # func02()
像這樣,我們先把func02註釋掉,直接調用func01是可以調用成功的,完全沒問題
但是我們再調用func02呢?一定會報錯,為什麼?這就涉及到一個知識點:
函數內部的屬性,都是有生命周期的,都是在函數執行期間
簡單來說就是func02存在於func01函數體內,func01調用執行完
它裡面的代碼就執行不瞭,如果想讓它存活執行下去,就要return出去
再找一個變量接收,那麼這樣,不管你函數裡怎麼樣,我就可以從內部使用外部的變量
所以調用這裡不能像上面那麼寫:
# 調用 text = func01() text(3) # 3為參數
這樣才算整整意義上的閉包
1.3 優點
內部函數可以使用外部變量
1.4 缺點
外部變量一直存在於內存中,不會在調用結束後釋放,占用內存
1.5 作用
實現python裝飾器
二、裝飾器 Decorator
2.1 定義
在不改變原函數的調用以及內部代碼情況下,為其添加新功能的函數
這個常見的裝飾器就是你拿到別人的第三方API,假如API接口不允許你修改
但是你覺得他寫的特別low,還需要添加某些功能,那我們就需要使用裝飾器
2.2 語法
def 函數裝飾器名稱(func): def wrapper(*args, **kwargs): 需要添加的新功能 return func(*args, **kwargs) return wrapper 原函數 = 內嵌函數 @函數裝飾器名稱 def 原函數名稱(參數): 函數體 原函數(參數)
2.3 本質
使用“@函數裝飾器名稱”修飾原函數,等同於創建與原函數名稱相同的變量,關聯內嵌函數;故調用原函數時執行內嵌函數。
原函數名稱 = 函數裝飾器名稱(原函數名稱)
2.4 裝飾器鏈
一個函數可以被多個裝飾器修飾,執行順序為從近到遠。
接下來我們寫一個裝飾器的小案例,來更加清楚一下裝飾的整個工作流程
故事情境是這樣的,主角是男人和女人,假設男人女人都是可以上班的,但是呢有不同
男人隻能是好好上班,不能生娃;女人可以好好上班,也可以生娃
當然我們別反駁啊,是有的國傢的男的也有生娃的技術,但是我們這裡就是按照我們設定好的來
那當我們調用 man() 的時候,打印 好好上班,你不能生娃
調用 woman() 的時候,打印 好好上班,你可以生娃
def man(): print("好好上班") def woman(): print("好好上班") man() woman()
那我們緊接著構建裝飾器,裝飾器名字無所謂,想怎麼定義就怎麼定義
# 裝飾器函數帶參數 def arg_func(sex): def func1(b_func): def func2(): if sex == 'man': print("你不可以生娃") if sex == 'woman': print("你可以生娃") return b_func() return func2 return func1 @arg_func(sex='man') def man(): print("好好上班") @arg_func(sex='woman') def woman(): print("好好上班") man() woman()
這個生成器大概的過程就是:
arg_func(sex='man'/'woman')()() > func1 func1() > func func() > print("你不可以生娃") or print("你可以生娃") > b_func # 然後判斷sex的值,最後return出去,拿到結果
我們看這個生成器啊,因為它這個函數這裡**def arg_func(sex)😗*這裡是默認接收一個函數名作為參數進來,但是現在參數有瞭,但是函數名不見瞭,怎麼辦,我們隻能是去在這個函數裡再次寫一個函數,再傳入函數名
這個就是相當於隻要是有傳遞參數的話,就要在寫一個函數套進去,因為你還有一個函數名要進行傳參
接下來我們看一下被裝飾的函數帶參數
def func1(func): def func2(x, y): print(x, y) x += 5 y += 5 return func(x, y) return func2 @func1 def num_sum(a, b): print(a + b) num_sum(1, 2)
這種裝飾器跟之前的相比,直觀的感受來說代碼減少,更加精簡,所以我們常用的也是這個較多
它總體來說流程變化不大,就是對於傳參的形式進行瞭變化,即采用函數最內部傳參
到此這篇關於Python必備基礎之閉包和裝飾器知識總結的文章就介紹到這瞭,更多相關Python閉包和裝飾器內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!