關於python的裝飾器decorator

剛接觸python,看到裝飾器相關的內容花了很多時間理解,參考了一些博客,這裏作一些總結。html

先定義一個簡單的函數foopython

def foo():
    print 'call foo()'

如今咱們想要計算次函數執行的時間,因而修改代碼以下app

import time

def foo():
    start = time.clock()
    print 'call foo()'
    end = time.clock()
    print 'using time:',end - start

思考一下,這樣作可以實現,但是若是我還想知道另外一個foo_1的運行時間,那我只能把上面新增長的代碼複製到foo_1這個函數裏面,十分麻煩,能不可以不要改變本來的函數,即計算時間的代碼不加在原本的函數裏面。函數

這應該不難,很容易想到能夠這樣寫code

import time
 
def foo():
    print 'call foo()'
 
def cal_time(func):
    start = time.clock()
    func()
    end =time.clock()
    print 'using time:', end - start
 
cal_time(foo)

這樣,若是還須要計算函數foo_1的時間,只須要cal_time(foo_1)就行了。htm

可是,這樣其實改變了函數本來的調用方式,開始咱們是這樣調用foo()
如今是cal_time(foo)blog

那麼若是如今須要修改foofoo_plus,我就必須更改n處調用了foo的代碼!get

還有更好的實現方式嗎?可否使調用foo()產生時調用cal_time(foo)的效果?
能夠想到,把cal_time(foo)的返回值賦給foo,看看下面的實現博客

import time
 
def foo():
    print 'call foo()'
 
# 定義一個計時器,傳入一個函數,並返回另外一個附加了計時功能的方法
def cal_time(func):
     
    # 定義一個內嵌的包裝函數,給傳入的函數加上計時功能的包裝
    def wrapper():
        start = time.clock()
        func()
        end =time.clock()
        print 'using time:', end - start
     
    # 將包裝後的函數返回
    return wrapper
 
foo = cal_time(foo)
foo()

這樣便無需改變原函數及其調用,想計算函數foo的用時,在函數調用foo()前,加上foo = cal_time(foo)便可。import

用Python提供的語法糖來下降字符輸入量。

import time
 
def cal_time(func):
    def wrapper():
        start = time.clock()
        func()
        end =time.clock()
        print 'using time:', end - start
    return wrapper
 
@cal_time               #定義函數時加上這一行與另外寫foo = cal_time(func):徹底等價
def foo():
    print 'call foo()'
 
foo()

若有錯漏,請指正

參考資料:
1.http://www.cnblogs.com/rollen...
2.https://www.liaoxuefeng.com/w...

相關文章
相關標籤/搜索