標籤:this 部分 元組 函數名 enc 分享 它的 glob else
(1)python的LEGB: LEGB是指:按照L>E>G>B 的順序優先順序進行變數尋找。 L:local函數內部範圍,是最底層的單個函數裡面; E:enclosing函數內部與內嵌函數之間,是有內建函式的函數裡面; G:global 全域範圍,是一個.py檔案中; B:build-in內建範圍,比如:tuple,list,元組。是所有.py檔案中。
(2)閉包 閉包是指:一個函數中內嵌了另一個函數,這個內嵌的函數會使用外部函數的參數變數,作為判決內嵌函數的不同運行模式的參考。最後外部函數會返回它的內嵌函數,即返回了函數對象地址,而這個內嵌函數就是我們說的閉包。用下面這個例子來說明:
def set_passline(passline): def cmp(val): if val >= passerine: print(‘Pass‘) else: print(‘failed‘) return cmpf_100 = set_passline(60)f_100(89)f_150 = set_passline(96)f_150(89)
set_passline返回的是內嵌函數cmp這個函數對象,不同的實參passline決定不同的cmp函數對象,這個內嵌函數cmp也就是閉包。 總之,閉包就是指引用外部函數的內嵌函數, 它的主要作用是:(1)封裝;(2)代碼複用 此外,閉包中引用的外部函數參數也可以是函數,此時作用是:將多個不同函數中相同的處理部分抽象出來,放入閉包進行封裝,而閉包又傳入函數對象,這樣,閉包中運行完相同處理部分後,就可以運行不同函數的特定代碼。例子如下:
def my_sum(*arg): print(‘my_sum‘) return sum(arg)def my_average(*arg): print(‘my_average‘) return sum(arg) / len(arg)def dec(func): # 閉包 def in_dec(*arg): print(‘in_dec()=‘, arg) # 將相同的處理部門進行封裝 if len(arg) == 0: return 0 for val in arg: if not isinstance(val, int): return 0 # 處理完相同部門,返回不同函數的特定處理 return func(*arg) return in_decmy_sum = dec(my_sum)print(my_sum(1, 2, 3, 4, 5, 6))print(my_sum(1, 2, 3, 4, 5, ‘6‘))my_average = dec(my_average)print(my_average(1, 2, 3, 4, 5, 6))print(my_average(1, 2, 3, 4, 5, ‘6‘))
運行結果為:
(3)裝飾器 裝飾器實質上就是對閉包的使用,通過封裝相同部分的代碼或者一些裝飾代碼,從而進行代碼重用(有點類似於設計模式中的"裝飾模式")。通過python解譯器的裝飾器文法糖(@dec,dec是閉包的外部函數名字)來顯示地使用閉包,將函數作為實參傳入閉包,最後裝飾器將閉封裝飾過的函數返回給被裝飾函數,即:bar = dec(bar)。使用例子如下:
def deco(func): print("this is deco") def in_deco(x,y): print(‘this is closure‘) func(x,y) return in_deco@deco #裝飾器的文法糖,會將其下面的函數當做函數對象實參func傳入deco, 相當於調用了bar = dec(bar)def bar(x,y): print("this is bar") print("%d+%d=%d" % (x,y,x+y))bar(2,4) 運行結果如下:
Python閉包和裝飾器