python 高級函數
來自專欄 python 全棧工程師2 人贊了文章
閉包
什麼是閉包:如果在一個內部函數里,對在外部作用域(但不是在全局作用域)的變數進行引用,那麼內部函數就被認為是閉包。
需要滿足的條件
1.一個函數內嵌套一個函數
2.外部函數的返回值必須是這個內部的函數
3.內部函數必須使用外部函數中的局部變數
def fun_1(): num_1=9 def fun_2(num_2): print(num_1+num_2) return fun_2f=fun_1() #現在f=fun_2f(8) #fun_2(8)輸出 17這時就稱fun_2為閉包
由於閉包引用了外部函數的局部變數,則外部函數的局部變數沒有及時釋放
def fun_2(): a=list() def fun(num): a.append(num) print(num) return a return fung1=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_oildef wall(): print("wall!")if __name__=="__main__": print("start painting") wall() 輸出ready to paint!start paintingred 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 oilred oil
nonlocal 聲明
nonlocal
聲明,作用是將變數標記為自由變數,也就意味著我們可以對做了 nonlocal
聲明的變數進行修改
def wall(): nums=0 oils=[] def paint_wall(color): nonlocal nums nums +=1 oils.append(color) print("Paint wall by color:"+color) print("Paint wall {} times".format(nums)) return oils return paint_wallif __name__ == __main__: white_wall=wall() white_wall("red") white_wall("yellow")輸出Paint wall by color:redPaint wall 1 timesPaint wall by color:yellowPaint wall 2 times
帶參數的裝飾器
既然裝飾器本質上就是一個函數,那裝飾器也可以傳參。那麼具體應該怎麼做呢?在 Python 中需要建立一個裝飾器工廠函數,把參數傳給它,再返回一個裝飾器,然後應用到要裝飾的函數上。
推薦閱讀:
※分析和代數原理(6)
※一年級數學應用題100道
※數學+X|原來認識時鐘有這麼大的學問!
※方舟子:要「賽先生」還是「佛先生」?
※Monte Carlo Method Homework 9