Python Decorator 裝飾器快速入門

Chao-Wei Peng
Sep 30, 2021
Photo by Spacejoy on Unsplash

Python 裝飾器是一個很特別的程式開發技巧,能夠將複雜的函式流程包裝、簡化成容易使用的宣告式語句。

本文很快的和大家說明 Python Decorator 最基本的技巧和運用方式。

回呼函式

在談裝飾器之前,我們要先聊聊回呼函式。回呼函式的運作邏輯,就是把函式透過參數傳遞到另一個函式中,如下程式碼範例:

def fn1(cb):
cb() # 呼叫傳遞進來的回呼函式,此範例最終印出 Hello
def fn2():
print("Hello")
# 呼叫 fn1 函式,將 fn2 函式透過參數傳遞到 fn1 函式中
# 透過參數傳遞到 fn1 函式中執行的 fn2 被稱為回呼函式
fn1(fn2)

裝飾器的入門

裝飾器其實就是一個精心設計的函式:裝飾器函式固定接收一個回呼函式參數,並且必須回傳一個函式供後續執行。

最簡單的裝飾器,只要直接將回呼函式回傳即可。回呼函式在裝飾器中被回傳後,自動被系統呼叫、執行。請參考範例如下:

# 定義裝飾器 fn1,其實就是一個函式,固定接收一個回呼函式參數
def fn1(cb):
return cb # 直接回傳回呼函式,系統會自動呼叫,此範例最終印出 Hello
# 使用裝飾器 fn1,在裝飾器名稱前面加上 @ 符號,下方則定義回呼函式
# 這是一個帶有 fn1 裝飾器的 fn2 函式
@fn1
def fn2():
print("Hello")
# 呼叫帶有裝飾器的函式 fn2
fn2() # 等同於上述範例的 fn1(fn2)

裝飾器的使用

概念上,我們利用裝飾器函式做前置工作,接著再執行實際呼叫的函式。以上述的例子來看,最後一行,執行帶有 fn1 裝飾器的 fn2 函式時,其實就是先執行 fn1 函式,然後再執行 fn2 函式。

以下範例的裝飾器會固定從檔案中取得資料,放入全域變數中,然後再把取得的資料印出來:

# 宣告全域變數 data
data=None
# 定義裝飾器 getData
def getData(cb):
global data
file=open("檔案路徑")
data=file.read()
file.close()
return cb
# 定義 show 函式,帶有裝飾器 getData
@getData
def show():
print(data)
# 呼叫帶有 getData 裝飾器的 show 函式
# 1. 先執行裝飾器函式 getData,讀取檔案資料放進全域變數 data
# 2. 接著執行函式 show,將全域變數 data 的資料印出來
show()

裝飾器是一個非常精緻的程式技巧,牽扯到複雜的函式運作流程。因此,建議大家可以把上述的範例都實際執行、修改看看,這樣能有效的幫助你掌握其中的細節哦。

如果對回呼函式的基礎有些疑惑,可以參考 Python 回呼函式教學影片

--

--