python functools.wraps裝飾器模塊


# -*-coding=utf-8 -*-
#實現一個函數執行后計算執行時間的功能
__author__ = 'piay' import time, functools def foo(): ''' 定義一個普通函數 :return: ''' print 'this is foo' foo() ''' 這里如果我們需要查看函數執行時間,修改為: ''' def foo1(): start_time = time.clock() print 'this is foo1' end_time = time.clock() print '執行時間為:', end_time - start_time foo1() ''' 如果我們其他的函數也需要執行時間,或者這個函數不需要執行時間,那么我們就需要復制到其他的函數中去 這是一種最差的方法 ''' def foo3(): print 'this is foo3' def timeit(func): ''' 我們可以考慮重新定義一個函數timeit,將foo的引用傳遞給他, 然后在timeit中調用foo並進行計時,這樣,我們就達到了不改動foo定義的目的 :param func: 傳入的函數 :return: ''' start_time = time.clock() func() end_time = time.clock() print 'used:', end_time - start_time timeit(foo3) ''' 這樣寫修改調用部分的代碼。原本我們是這樣調用的:foo3(),現在變成timeit(foo),這樣的話,如果foo在N處都被調用了, 你就不得不去修改這N處的代碼。或者更極端的,考慮其中某處調用的代碼無法修改這個情況,比如:這個函數是你交給別人使用的。 ''' ''' 想想辦法不修改調用的代碼;如果不修改調用代碼,也就意味着調用foo()需要產生調用timeit(foo)的效果。我們可以想到將timeit賦值給foo, 但是timeit似乎帶有一個參數……想辦法把參數統一吧!如果timeit(foo)不是直接產生調用效果, 而是返回一個與foo參數列表一致的函數的話……就很好辦了,將timeit(foo)的返回值賦值給foo,然后,調用foo()的代碼完全不用修改! ''' def foo4(): print 'this is foo4' # 定義一個計時器,傳入一個,並返回另一個附加了計時功能的方法 def timeit4(func): # 定義一個內嵌的包裝函數,給傳入的函數加上計時功能的包裝 def wrapper(): start_time = time.clock() func() end_time = time.clock() print 'used:', end_time - start_time # 將包裝后的函數返回 return wrapper foo_1 = timeit(foo4) ''' 上面的代碼就類似裝飾器了,可以修改為如下: ''' @timeit4 # 定義上加上這一行與另外寫foo = timeit(foo)完全等價 def foo5(): print 'this is foo5' foo5() ''' ----------------------------------------------- 使用functools.wraps(func)裝飾器實現功能 ''' def timeit_3_for_wraps(func): @functools.wraps(func) def wrapper(): start=time.clock() func() end=time.clock() print 'used:',end-start return wrapper @timeit_3_for_wraps def foo6(): print 'this is foo6' foo6()

 這里實現一個完整的判斷是否帶參數的裝飾器:

# -*-coding=utf-8 -*-
__author__ = 'piay'
import functools, time
'''
一個函數執行前打印開始執行,執行完后打印執行完成,記錄執行時間
'''

def log(text):
    if callable(text):  # 參數如果是函數,說明裝飾器不帶參傳過來,text是一個函數
        @functools.wraps(text)
        def wrapper(*args, **kwargs):
            start = time.clock()
            print '這是不帶參數的裝飾器,開始執行'
            f = text(*args, **kwargs)  #執行本身的函數 text()
            end = time.clock()
            print "結束執行:", end - start
            return f  # 返還原函數
        return wrapper

    elif not callable(text):  # text是參數,不是函數
        def decarator(func):
            @functools.wraps(func)
            def warpper(*args, **kwargs):
                start = time.clock()
                print '這是不帶參數的裝飾器,開始執行,參數為:'+text
                f = func(*args, **kwargs)
                end=time.clock()
                print "結束執行:",end-start
                return f  #返還原函數
            return warpper
        return decarator
    else:
        print '請檢查是否正確'


@log
def add1(x,y):
    print x+y

@log('222')
def add2(x,y):
    print  x+y

add1(1,2)
add2(2,3)

 執行結果:

D:\Python27\python.exe D:/Python/functools_study/完整的裝飾器.py
這是不帶參數的裝飾器,開始執行
3
結束執行: 5.08444509009e-05
這是不帶參數的裝飾器,開始執行,參數為:222
5
結束執行: 2.49333364995e-05

Process finished with exit code 0


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM