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