裝飾子 (decorator) 是定義函數 (function) 或方法 (method) 的一種簡化語法,主要是讓新定義的函數,可以有效減少繁複的用函數當參數 (parameter) ,或是函數回傳函數的寫法。
先看一個簡單的例子,這裡函數 f2() 最後回傳 f2() 內的巢狀函數 f3() ,而且 f2() 另需要一個 func 函數當參數,因此如果要用 f2() 的功能,就用 f4 取得 f2() 的回傳值 (return value) , f2() 同時以 f1() 當參數,基本上新的函數 f4() 就是替參數字串插入兩個前綴字元
def f1(name):
return ":" + name
def f2(func):
def f3(name):
return "." + func(name)
return f3
f4 = f2(f1)
print(f4("John"))
#《程式語言教學誌》的範例程式
# http://kaiching.org/
# 檔名:decorator01.py
# 功能:示範裝飾子
# 作者:張凱慶
於命令列執行以上程式,結果如下
$ python3 decorator01.py |
.:John |
$ |
如果將原本 f1() 改成加上 f2() 裝飾子,就是在函數 f5() 定義的上一行用小老鼠符號加上 f2 ,這樣的函數 f5() 就跟 f4 一樣,相對就少掉一步函數當參數及函數回傳函數的設定過程
def f2(func):
def f3(name):
return "." + func(name)
return f3
@f2
def f5(name):
return ":" + name
print(f5("Peter"))
#《程式語言教學誌》的範例程式
# http://kaiching.org/
# 檔名:decorator02.py
# 功能:示範裝飾子
# 作者:張凱慶
於命令列執行以上程式,結果如下
$ python3 decorator02.py |
.:Peter |
$ |
如果需要再多一個前綴,此時定義新的函數 f6() ,用 f6() 加入新的前綴,然後另外在新函數 f8() 的定義上兩行加上 f2 及 f6 的裝飾子
def f2(func):
def f3(name):
return "." + func(name)
return f3
def f6(func):
def f7(name):
return "|" + func(name)
return f7
@f2
@f6
def f8(name):
return ":" + name
print(f8("Mary"))
#《程式語言教學誌》的範例程式
# http://kaiching.org/
# 檔名:decorator03.py
# 功能:示範裝飾子
# 作者:張凱慶
於命令列執行以上程式,結果如下
$ python3 decorator03.py |
.|:Mary |
$ |
裝飾子比較常用在定義類別方法 (class method) 上,定義類別方法前要加上裝飾子 @classmethod ,因為 classmethod() 本身就是內建函數 (built-in function) ,如果不用裝飾子,定義類別方法的步驟就相對繁雜很多。
class Demo:
@classmethod
def demo(cls):
print("Demo")
Demo.demo()
#《程式語言教學誌》的範例程式
# http://kaiching.org/
# 檔名:decorator04.py
# 功能:示範裝飾子
# 作者:張凱慶
於命令列執行以上程式,結果如下
$ python3 decorator04.py |
Demo |
$ |
相關教學影片