Python Decorator 裝飾器
裝飾器是Python提供的語法糖,常常用來將函式加入一些固定功能
也會拿來將函式註冊成特殊功能
基本語法
1 | def decorator(func): |
回傳結果:
1 | 開始執行 |
讓我來解說一下這是如何運作的:
解說
首先,你可以將裝飾器理解為一個「有固定形式」的函數工廠
可以將你的函數加上一些固定的功能
外部傳入
當你在你的函數上加上@decorator
的時候,你做的事是將a_function
函數物件傳進decorator()
所以以下兩種寫法是等價的
1 | def decorator(func): |
1 | def decorator(func): |
函數內部
有了基本理解,我們來說說decorator函數內是怎麼運作的
首先,他接收了一個函數物件
別忘了,Python是物件導向的語言,連函數也是一個物件,所以當然可以當作參數傳入另一個函數
接著,細看函數內部:
1 | def wrapper(): |
這個函數會先執行自己的動作(開始執行、結束執行)
然後在恰當的位置去執行原本被傳進來的函數,再把原本函數的結果傳回去
所以基本上函數執行結果不被影響,而是另開一個函數
看起來像是修改了a_function()
,但實際上是另外開一個函數做處理
最後看整個裝飾器
1 | def decorator(func): |
decorator
最後會返回我們自己另外開的函數
所以最後你執行a_function()
時,實際上是執行修改過的wrapper()
參數
如果我們裝飾的a_function
會需要參數怎麼辦?
這時候我們可以善用*args
和**kwargs
這兩個用法可以讓我們接收一整串沒有對應名稱的參數,或是有對應名稱的參數
1 | def decorator(func): |
範例
此處以執行時印出時間來做範例
1 | # 引入時間模組來取用當前時間 |
輸出結果:
1 | 開始時間:2024-12-20 11:55:31.696425 |
由此方法,我們可以很有效率的為多個函數做額外處理
比如說印出開始執行的時間、開始執行時記數等等
而且裝飾器可以不只使用一次,能夠在多個函數都需要相同動作時高效率的工作
也像開頭提到的,有些套件會以此來註冊函數來執行特殊動作
如flask會用@app.route
來註冊成一個路徑
Discord也會愈用@bot.command()
來註冊成指令
本部落格所有文章除特別聲明外,均採用CC BY-NC-SA 4.0 授權協議。轉載請註明來源 Sharkspeare筆記!
評論