前言
裝飾器 (decorator),可以幫助我們快速地用簡易的方式達到修飾 function 的效果,
以本篇的例子來說,我們可以替原本沒有計時功能的 function,
以一行的方式直接新增計時的功能。
範例程式碼
from functools import wraps
import time
def WongWongTimer(func):
@wraps(func)
def wrap(*args, **kargs):
time_start = time.time()
value = func(*args, **kargs)
time_end = time.time()
time_spend = time_end - time_start
#print(f"[{func.__module__}.{func.__name__}] cost time: {time_spend}")
print(f"[WongWongTimer][{func.__qualname__}] cost time: {time_spend}")
return value
return wrap
使用方式 – 單純版,撰寫 wongwong_utils.py
個人是存成 wongwong_utils.py 後,
要使用時,只需要在想要偵測的 function 前一行加上這個「@WongWongTimer」即可!
- 範例如下:
from wongwong_utils import WongWongTimer
@WongWongTimer
def test():
print("Hello World!!!")
test()
使用方式 – 大型程式重複使用版 (放入指定資料夾並設定 __init__.py
)
通常在比較大型的資料夾中,我們會將此類工具嘗試放入資料夾當中。
個人放的方法為,將上面那段程式碼存在 wongwong_utils.py 中,
並把這個檔案放在一個名為 「utils」 的資料夾當中。
參考下圖架構:
- main.py
- utils
__init__.py
wongwong_utils.py
我們去修改 __init__.py
,更方便我們去 import 這支程式。
「 __init__
」.py 的功能,主要是讓一個資料夾內的所有內容可以被模組化,
我們可以使用 import 資料夾名稱,來直接引入所有我們需要的、且在資料將底下的模組。
撰寫 utils 資料夾底下的 init.py (使 utils 成為 package)
from .wongwong_utils import *
__all__ = ['WongWongTimer'']
撰寫 utils 資料夾底下的 wongwong_utils.py
from functools import wraps
import time
def WongWongTimer(func):
@wraps(func)
def wrap(*args, **kargs):
time_start = time.time()
value = func(*args, **kargs)
time_end = time.time()
time_spend = time_end - time_start
#print(f"[{func.__module__}.{func.__name__}] cost time: {time_spend}")
print(f"[WongWongTimer][{func.__qualname__}] cost time: {time_spend}")
return value
return wrap
實作範例
from utils import WongWongTimer
@WongWongTimer
def test():
print("Hello World!!!")
test()
因為上面已經把 utils 包裝成一份 package,
所以我們可以直接呼叫此 package 內的 WongWongTimer 模組來使用。
from utils import WongWongTimer
要使用時,只需要在想要偵測的 function 前一行加上這個「@WongWongTimer」即可!
注意:utils package 必須在「不同的資料夾」底下才可以使用。
因為被打包的 package 不包含本身
(例如說我們想在 utils 資料夾底下這樣 import WongWongTimer,會找不到不能使用)
未使用 init.py 加工成 utils package 的方法也可以
如果是一般未經過資料夾 init.py 加工的方法,我們也可以使用
from utils.wongwong_utils import WongWongTimer
可以簡記為 「from [file] import [module]」
前面的 「from utils.wongwong_utils」 代表是尋找 .py 的路徑
後面的 「import WongWongTimer」 就是要 import 的 class/function
延伸討論
有點小可惜的是,這個方便的 decorator 只能夠給 funciton 使用 (但也夠方便了),
不能給單一行程式碼使用 (需要先包進 function 當中)。