$如何用Python裝飾器實現一個代碼計時器?

有時候咱們很但願看到程序中某個函數或某個代碼段的耗時狀況,那麼該如何辦呢?本文用兩種方式實現了代碼計時器的功能,第一種方式是採用裝飾器來實現,第二種方式採用上下文管理器實現。python

其實計算代碼的運行時間,最樸素的想法就是先記錄下來某段代碼剛開始運行時的時間,等到運行完以後,再看一下結束時的時間,最後和開始運行時的時間求個差值,就是這段代碼所花費的時間。函數

下面兩種計時器的實現方式就是用到這樣一種很是簡單的方法。code

用裝飾器實現函數計時器

# coding:utf-8
from functools import wraps
import time

def func_timer(function):
    '''
    用裝飾器實現函數計時
    :param function: 須要計時的函數
    :return: None
    '''
    @wraps(function)
    def function_timer(*args, **kwargs):
        print '[Function: {name} start...]'.format(name = function.__name__)
        t0 = time.time()
        result = function(*args, **kwargs)
        t1 = time.time()
        print '[Function: {name} finished, spent time: {time:.2f}s]'.format(name = function.__name__,time = t1 - t0)
        return result
    return function_timer

@func_timer
def test(x,y):
    s = x + y
    time.sleep(1.5)
    print 'the sum is: {0}'.format(s)

if __name__ == '__main__':
    test(1,2)
    # 輸出結果
    '''
    [Function: test start...]
    the sum is: 3
    [Function: test finished, spent time: 1.50s]
    '''

用上下文管理器實現代碼段計時器

上下文管理器實際上是一個實現了__enter____exit__兩個特殊方法的對象,能夠用with語法調用。能夠參照操做文件的with oepn操做,好比:orm

with open('data.txt','r') as fin:
    data = fin.read()

使用with上下文管理器操做文件的好處就是,不用擔憂文件使用完以後忘記關閉,上下文管理器會自動幫你關閉。對象

那麼下面就用上下文管理器來實現一個代碼段計時器:utf-8

# coding:utf-8
from functools import wraps
import time

class MyTimer(object):
    '''
    用上下文管理器計時
    '''
    def __enter__(self):
        self.t0 = time.time()

    def __exit__(self, exc_type, exc_val, exc_tb):
        print '[finished, spent time: {time:.2f}s]'.format(time = time.time() - self.t0)

def test(x,y):
    s = x + y
    time.sleep(1.5)
    print 'the sum is: {0}'.format(s)

if __name__ == '__main__':
    with MyTimer() as t:
        test(1,2)
        time.sleep(1)
        print 'do other things'
    # 輸出:
    '''
    the sum is: 3
    do other things
    [finished, spent time: 2.53s]
    '''

總結

能夠看出,上述兩種計時器的實現方式各有優缺點,用裝飾器實現的計時器優勢是使用起來很是方便,給要計時的函數加一個裝飾器便可,但不足之處是沒法對一個代碼片斷進行計時。而用上下文管理器實現的計時器就能夠對任意一個代碼段進行計時,彌補了裝飾器計時器的缺陷。it

具體用哪一種計時器,仍是要根據實際狀況來選擇。io

相關文章
相關標籤/搜索