首先我們來了解下閉包,什么是閉包呢?看一下維基百科給出的解析:
閉包(英語:Closure),又稱詞法閉包(Lexical Closure)或函數(shù)閉包(function closures),是引用了自由變量的函數(shù)。這個被引用的自由變量將和這個函數(shù)一同存在,即使已經(jīng)離開了創(chuàng)造它的環(huán)境也不例外。所以,有另一種說法認(rèn)為閉包是由函數(shù)和與其相關(guān)的引用環(huán)境組合而成的實體。閉包在運(yùn)行時可以有多個實例,不同的引用環(huán)境和相同的函數(shù)組合可以產(chǎn)生不同的實例。
看了上面的解釋,你可能已經(jīng)懂了,也可能還是有點懵 B
def x(id): def y(name): print ('id:', id, 'name:', name) return yy = x('ityard')y('程序之間')
通過上面的示例,我們會發(fā)現(xiàn)閉包與類有一些相似,比如:它們都能實現(xiàn)數(shù)據(jù)的封裝、方法的復(fù)用等;此外,通過使用閉包可以避免使用全局變量,還能將函數(shù)與其所操作的數(shù)據(jù)關(guān)連起來。
裝飾器(decorator)也稱裝飾函數(shù),是一種閉包的應(yīng)用,其主要是用于某些函數(shù)需要拓展功能,但又不希望修改原函數(shù),它就是語法糖,使用它可以簡化代碼、增強(qiáng)其可讀性,當(dāng)然裝飾器不是必須要求被使用的,不使用也是可以的,Python 中裝飾器通過 @
符號來進(jìn)行標(biāo)識。
裝飾器可以基于函數(shù)實現(xiàn)也可基于類實現(xiàn),其使用方式基本是固定的,看一下基本步驟:
定義裝飾函數(shù)(類)
定義業(yè)務(wù)函數(shù)
在業(yè)務(wù)函數(shù)上添加 @裝飾函數(shù)(類)名
接下來通過示例來作進(jìn)一步了解。
基于函數(shù)
# 裝飾函數(shù)def funA(fun): def funB(*args, **kw): print('函數(shù) ' + fun.__name__ + ' 開始執(zhí)行') fun(*args, **kw) print('函數(shù) ' + fun.__name__ + ' 執(zhí)行完成') return funB@funA# 業(yè)務(wù)函數(shù)def funC(name): print('Hello', name)funC('Jhon')
裝飾函數(shù)也是可以接受參數(shù)的,如下所示:
# 裝飾函數(shù)def funA(flag): def funB(fun): def funC(*args, **kw): if flag == True: print('==========') elif flag == False: print('----------') fun(*args, **kw) return funC return funB@funA(False)# 業(yè)務(wù)函數(shù)def funD(name): print('Hello', name)funD('Jhon')
Python 中還支持多個裝飾器同時使用,比如裝飾函數(shù)為:funA、funD,業(yè)務(wù)函數(shù)為:funH,使用方式如下所示:
@funA@funDdef funH(): ...
基于類
裝飾器除了基于函數(shù)實現(xiàn),還可以基于類實現(xiàn),看下示例:
class Test(object): def __init__(self, func): print('函數(shù)名是 %s ' % func.__name__) self.__func = func def __call__(self, *args, **kwargs): self.__func()@Testdef hello(): print('Hello ...') hello()
Python 裝飾器的 @...
相當(dāng)于將被裝飾的函數(shù)(業(yè)務(wù)函數(shù))作為參數(shù)傳入裝飾函數(shù)(類)。