首頁 > 軟體

Python裝飾器實現函數執行時間的計算

2022-02-13 13:00:34

個人理解

裝飾器: 通過閉包和將一個函數作為另一個函數引數的形式,實現已有功能的靈活呼叫

例如:

首先設定了一個time_master的計時器函數,在執行某個函數的同時,用來統計函數的耗時

那麼,如果想知道函數效能, 每次寫完新的函數後,都放到time_master函數中執行一次來統計。

——> 這是比較麻煩的。相當於雖然有了一個稱,但是所有的新買食材都需要逐個放到稱上去稱一遍,來獲得食材的重量

——> 如果能夠省略掉一次一次上稱這個步驟就好了

——> 比如每個食材進門的同時就從稱上走過,那進來的同時,也就有了重量的資料

例子:呼叫函數的同時對函數進行計時

實現方法1:@語法糖

程式碼:

# 涉及到計時,需要引入time模組
import time
# 定義一個對函數執行耗時統計的計時器,用func作為形參來代替需要統計的函數
def time_master(func):
    def call_func():
        print("計時器開始:函數開始呼叫:")
        start_time = time.time()
        func()
        end_time = time.time()
        print('計時器結束,函數呼叫完成')
        return print(f'計時器結果返回:函數呼叫耗時{end_time-start_time:.2f}')
    return call_func
@time_master 
# 即在呼叫myfunc函數時,不是直接呼叫myfunc
# 而是將myfunc函數作為一個引數放入到@的裝飾器中,然後去呼叫裝飾器
def myfunc():
    time.sleep(2)
    print('myfunc函數執行')
    time.sleep(4)
    print('myfunc函數執行結束')
myfunc()  # 呼叫myfunc

實現結果:

計時器開始:函數開始呼叫:
myfunc函數執行
myfunc函數執行結束
計時器結束,函數呼叫完成
計時器結果返回:函數呼叫耗時6.01

實現方法2:閉包

可以理解成,本來定義了一個myfunc的函數,但這個函數本身沒有計時的功能,而恰巧有一個time_master的函數,在執行子函數的同時,還會對子函數進行計時

因此,通過重新定義 myfunc = time_master(myfunc), 即將myfunc作為引數傳入到time_master中,作為myfunc函數的新定義

程式碼:

import time
def time_master(func):
    def call_func():
        print("計時器開始:函數開始呼叫:")
        start_time = time.time()
        func()
        end_time = time.time()
        print('計時器結束,函數呼叫完成')
        print(f'計時器結果返回:函數呼叫耗時{end_time-start_time:.2f}')
    return call_func
def myfunc():
    time.sleep(2)
    print('myfunc函數執行')
    time.sleep(4)
    print('myfunc函數執行結束')
myfunc = time_master(myfunc)  # 和實現方法一的差距就在於是在myfunc前面@裝飾器,還是在後面對myfunc函數進行二次定義
myfunc()

實現結果:

計時器開始:函數開始呼叫:
myfunc函數執行
myfunc函數執行結束
計時器結束,函數呼叫完成
計時器結果返回:函數呼叫耗時6.01

實現方式1和 2的差異

實現方式1和實現方式2: 其實沒什麼區別,無非是一開始就用@time_master來規定,還是定義完myfunc之後,再多做一步讓myfun放入time_master中去執行

總結

本篇文章就到這裡了,希望能夠給你帶來幫助,也希望您能夠多多關注it145.com的更多內容!               


IT145.com E-mail:sddin#qq.com