本文實例講述了Python裝飾器(decorator)定義與用法。分享給大家供大家參考,具體如下:
什么是裝飾器(decorator)
簡單來說,可以把裝飾器理解為一個包裝函數的函數,它一般將傳入的函數或者是類做一定的處理,返回修改之后的對象.所以,我們能夠在不修改原函數的基礎上,在執行原函數前后執行別的代碼.比較常用的場景有日志插入,事務處理等.
裝飾器
最簡單的函數,返回兩個數的和
def calc_add(a, b): return a + bcalc_add(1, 2)
但是現在又有新的需求,計算求和操作耗時,很簡單,求和前獲取一下時間,求和后再獲取一次,求差即可
import datetimedef calc_add(a, b): start_time = datetime.datetime.now() result = a + b end_tiem = datetime.datetime.now() print "result:", result, "used:", (end_tiem - start_time).microseconds, "μs" return resultcalc_add(1, 2)
現在呢,函數calc_diff(a, b),計算a-b,也想計算減法操作的時間差,很好辦,把那段代碼復制過去.但是假如我們現在想編的是一個數學函數庫,各種函數都想計算其執行耗時,總不能一個一個復制代碼,想個更好的辦法.
我們知道,在Python中函數也是被視為對象的,可以作為參數傳遞,那么假如把計算耗時的獨立為一個單獨的函數calc_spend_time(),然后把需要計算耗時的函數例如calc_add的引用傳遞給它,在calc_spend_time中調用calc_add,這樣所有的需要計算耗時的函數都不用修改自己的代碼了.
def calc_spend_time(func, *args, **kargs): start_time = datetime.datetime.now() result = func(*args, **kargs) end_tiem = datetime.datetime.now() print "result:", result, "used:", (end_tiem - start_time).microseconds, "μs"def calc_add(a, b): return a + bcalc_spend_time(calc_add, 1, 1)# calc_spend_time(calc_add, a=1, b=2)
看起來也不錯,負責計算的函數不用更改,只需調用的時候作為參數傳給計算時間差的函數.但就是這,調用的時候形式變了,不再是clac(1, 2),而是calc_spend_time(clac_add, 1, 2),萬一calc_add大規模被調用,那么還得一處一處找,然后修改過來,還是很麻煩.如果想不修改代碼,就得使clac()和calc_spend_time(clac)效果一樣,那么可以在calc_spend_time()里把傳入的clac包裝一下,然后返回包裝后的新的函數,再把返回的包裝好的函數賦給clac,那么calc()的效果就和上例calc_spend_time(calc())效果一樣.
import datetimedef calc_spend_time(func): def new_func(a, b): start_time = datetime.datetime.now() result = func(a, b) end_tiem = datetime.datetime.now() print "result:", result, "used:", (end_tiem - start_time).microseconds, "μs" return new_funcdef calc_add(a, b): return a + bcalc_add = calc_spend_time(calc_add)calc_add(1, 2)
新聞熱點
疑難解答