這個(gè)概念一開始真的很難理解,以至于現(xiàn)在我去寫這篇日志,我都不確定是否真的理解了裝飾器的意義。首先,假定我們定義一個(gè)函數(shù)date():
def date():
print("2017/9/17")
這個(gè)函數(shù)的作用很簡(jiǎn)單,就是打印日期。但是如果我們現(xiàn)在希望,在正常書寫調(diào)用date()函數(shù)時(shí),它可以申明自己已經(jīng)被調(diào)用(也就是額外加上一個(gè)功能)。
如果不額外強(qiáng)求正常書寫:
def call_me(func):
print("{} is running").formate(func))
func()
def date():
print("2017/9/17")
call_me(date)
以上函數(shù)就可以實(shí)現(xiàn)這個(gè)功能。
但是,有個(gè)問(wèn)題。因?yàn)槲抑皇窍M谖艺{(diào)用date()時(shí),可以附帶上一些功能,而不需要改寫一些代碼。上面的實(shí)現(xiàn)方法,已經(jīng)完全看不到直接調(diào)用date()的影子了。這個(gè)時(shí)候,可以用裝飾器實(shí)現(xiàn):
def call_me(func):
def wrapper():
print("{} is running").formate(func))
return func()
return wrapper()
def date():
print("2017/9/17")
date = call_me(date)
date()
這時(shí),我們想使用附帶功能的date()函數(shù),也一樣只需要調(diào)用date(),而不是用call_me(date)。其中call_me()就是一個(gè)裝飾器。簡(jiǎn)單點(diǎn)說(shuō),其實(shí),call_me()是把額外的功能連同date()本身封裝到了一起。call_me()本身返回了一個(gè)函數(shù)wrapper(),語(yǔ)句date = call_me(date)相當(dāng)于是date = wrapper,那么調(diào)用了date()就相當(dāng)于調(diào)用了wrapper(),而wrapper()函數(shù)就是一個(gè)帶有額外功能的date()。
現(xiàn)在最新的實(shí)例看起來(lái)還不夠簡(jiǎn)潔,因?yàn)槲覀兊慕K極目的是,越簡(jiǎn)單越好。這時(shí),就要用到@。新的實(shí)例如下:
def call_me(func):
def wrapper():
print("{} is running").formate(func))
return func()
return wrapper()
@call_me
def date():
print("2017/9/17")
date()
這樣就是實(shí)現(xiàn)了我們的最初目的?,F(xiàn)在看起來(lái),call_me就像是裝飾一樣在date()函數(shù)前面。運(yùn)行的結(jié)果是這樣的:
>>>date is running
2017/9/17
我自己對(duì)裝飾器的理解比較粗略,也就只能闡述于此,紕漏甚多。