閉包
什麼是閉包:如果在乙個內部函式裡,對在外部作用域(但不是在全域性作用域)的變數進行引用,那麼內部函式就被認為是閉包。
需要滿足的條件
1.乙個函式內巢狀乙個函式
2.外部函式的返回值必須是這個內部的函式
3.內部函式必須使用外部函式中的區域性變數
def fun_1():
num_1=9
def fun_2(num_2):
print(num_1+num_2)
return fun_2
f=fun_1() #現在f=fun_2
f(8) #fun_2(8)
輸出 17
這時就稱fun_2為閉包
由於閉包引用了外部函式的區域性變數,則外部函式的區域性變數沒有及時釋放
def fun_2():
a=list()
def fun(num):
print(num)
return a
return fun
g1=fun_2()
g2=g1(2)
print('****',g2)
g3=g1(3)
print('*****',g3)
輸出結果
2**** [2]
3***** [2, 3]
當執行fun_2函式時,變數a被建立。執行g1(2)時,列表a新增乙個值2。執行g2(3)時,列表a又新增了乙個值。我們知道乙個函式內的區域性變數的生命週期是從執行函式開始到到結束。而現在我們函式已經執行完了,按道理來講區域性變數a應該清除才對。這就是因為閉包的原因,上面也說了閉包使用了外部函式的區域性變數,這就導致區域性變數a一直在記憶體中無法釋放,
占用記憶體。
為什麼使用閉包?
閉包就是為了不懂原函式的**,還要給它增加新功能的乙個手段
通過外面的一層層函式傳遞的引數,讓最內層函式直接呼叫外層函式的**,增加了新的功能。
優點:閉包優化了變數,原來需要類物件完成工作,閉包也可以完成
缺點:由於閉包引用了外部函式的區域性變數,則外部函式的區域性變數 沒有完全釋放,占用記憶體。
裝飾器定義:裝飾器本身是乙個可呼叫物件,接收乙個函式作為引數,然後將其返回或替換成另乙個函式或可呼叫物件。可以理解成,原來那是一堵白牆,經過了一層裝飾,這層裝飾可能是漆也可能把牆掏空鑲進一層**變得金光閃閃,最後呈現在你眼前的就是裝飾後的樣子。
可以把它完全當成常規函式來呼叫,其引數是另乙個函式。裝飾器有兩大特徵,一是能把被裝飾的函式替換成其他函式,二是裝飾器在載入函式時立即執行。
def read_oil(func):
print("ready to paint!")
def red_wall_func():
print("red wall")
return red_wall_func
@read_oil
def wall():
print("wall!")
if __name__=="__main__":
print("start painting")
wall()
輸出ready to paint!
start painting
red wall
可以看出,裝飾器red_oil
將函式wall
替換成了另乙個函式,就好比在原來的牆上刷了一層紅漆。而裝飾器在被裝飾的函式被定義時立即執行,而被裝飾的函式在執行的時候才執行,這也是匯入時和執行時的區別。
函式中變數的作用範圍
red_paint="red oil"
def wall(paint):
print(paint)
global red_paint
print(red_paint)
if __name__ == '__main__':
wall("yelloow oil")
輸出yelloow oil
red oil
nonlocal 宣告
nonlocal
宣告,作用是將變數標記為自由變數,也就意味著我們可以對做了nonlocal
宣告的變數進行修改
def wall():
nums=0
oils=
def paint_wall(color):
nonlocal nums
nums +=1
print("paint wall by color:"+color)
print("paint wall {} times".format(nums))
return oils
return paint_wall
if __name__ == '__main__':
white_wall=wall()
white_wall("red")
white_wall("yellow")
輸出paint wall by color:red
paint wall 1 times
paint wall by color:yellow
paint wall 2 times
既然裝飾器本質上就是乙個函式,那裝飾器也可以傳參。那麼具體應該怎麼做呢?在 python 中需要建立乙個裝飾器工廠函式,把引數傳給它,再返回乙個裝飾器,然後應用到要裝飾的函式上。 python 函式高階 python 函式高階
形參角度 萬能引數 動態接收位置引數 args 動態接收關鍵字引數 kwargs 的魔性用法 函式定義時 代表聚合。他將所有的位置引數 聚合成乙個元組,賦值給了args 函式定義時 將所有的關鍵字引數聚合成乙個字典中,將這個字典賦給了 kwargs 和 在函式的呼叫時 代表打散 僅限關鍵字引數 de...
Python高階 函式高階
閉包 closure 常規函式中可以在函式的引數中新增引數的預設值來簡化函式的操作,偏函式也可以做到這一點,而且會更加的方便管理函式的操作。通過內建模組functools的partial進行定義和處理 語法結構 新函式名稱 functools.partial 函式名稱,預設賦值引數 例如 全域性函式...
python 函式 高階函式
filter 函式是 python 內建的另乙個有用的高階函式,filter 函式接收乙個函式 f 和乙個list,這個函式 f 的作用是對每個元素進行判斷,返回 true或 false,filter 根據判斷結果自動過濾掉不符合條件的元素,返回由符合條件元素組成的新list。例如判斷奇偶數 def...