1. 程式人生 > >Python閉包和裝飾器

Python閉包和裝飾器

global col line AR bar lis 它的 class failed

(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 cmp f_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_dec my_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閉包和裝飾器