本文實(shí)例講述了Python中的裝飾器用法。分享給大家供大家參考。具體分析如下:
這里還是先由stackoverflow上面的一個(gè)問題引起吧,如果使用如下的代碼:
代碼如下:@makebold
@makeitalic
def say():
return "Hello"
打印出如下的輸出:
<b><i>Hello<i></b>
你會(huì)怎么做?最后給出的答案是:
代碼如下:def makebold(fn):
def wrapped():
return "<b>" + fn() + "</b>"
return wrapped
def makeitalic(fn):
def wrapped():
return "<i>" + fn() + "</i>"
return wrapped
@makebold
@makeitalic
def hello():
return "hello world"
print hello() ## 返回 <b><i>hello world</i></b>
現(xiàn)在我們來(lái)看看如何從一些最基礎(chǔ)的方式來(lái)理解Python的裝飾器。
裝飾器是一個(gè)很著名的設(shè)計(jì)模式,經(jīng)常被用于有切面需求的場(chǎng)景,較為經(jīng)典的有插入日志、性能測(cè)試、事務(wù)處理等。裝飾器是解決這類問題的絕佳設(shè)計(jì),有了裝飾器,我們就可以抽離出大量函數(shù)中與函數(shù)功能本身無(wú)關(guān)的雷同代碼并繼續(xù)重用。概括的講,裝飾器的作用就是為已經(jīng)存在的對(duì)象添加額外的功能。
1.1. 需求是怎么來(lái)的?
裝飾器的定義很是抽象,我們來(lái)看一個(gè)小例子。
代碼如下:def foo():
print 'in foo()'
foo()
這是一個(gè)很無(wú)聊的函數(shù)沒錯(cuò)。但是突然有一個(gè)更無(wú)聊的人,我們稱呼他為B君,說(shuō)我想看看執(zhí)行這個(gè)函數(shù)用了多長(zhǎng)時(shí)間,好吧,那么我們可以這樣做:
代碼如下:import time
def foo():
start = time.clock()
print 'in foo()'
end = time.clock()
print 'used:', end - start
foo()
很好,功能看起來(lái)無(wú)懈可擊。可是蛋疼的B君此刻突然不想看這個(gè)函數(shù)了,他對(duì)另一個(gè)叫foo2的函數(shù)產(chǎn)生了更濃厚的興趣。
怎么辦呢?如果把以上新增加的代碼復(fù)制到foo2里,這就犯了大忌了~復(fù)制什么的難道不是最討厭了么!而且,如果B君繼續(xù)看了其他的函數(shù)呢?
1.2. 以不變應(yīng)萬(wàn)變,是變也
還記得嗎,函數(shù)在Python中是一等公民,那么我們可以考慮重新定義一個(gè)函數(shù)timeit,將foo的引用傳遞給他,然后在timeit中調(diào)用foo并進(jìn)行計(jì)時(shí),這樣,我們就達(dá)到了不改動(dòng)foo定義的目的,而且,不論B君看了多少個(gè)函數(shù),我們都不用去修改函數(shù)定義了!
代碼如下:import time
def foo():
print 'in foo()'
新聞熱點(diǎn)
疑難解答
圖片精選