15. 裝飾器
對於某些函式執行之前或之後要加入某些動作或檢查,但是又不修改那些函式的內容(讓動作或檢查可以容易的加入或移除),此時可以用裝飾器(decorator)完成此項工作。
(1) 將輸出的結果改為大寫
以下是一個例子:
def myDecorator(func):
def wrapper(*args, **kwargs):
r = func(*args, **kwargs)
if isinstance(r, str):
return r.upper()
else:
return r
return wrapper
@myDecorator
def myname(name):
return name第11行用@myDecorator宣告一個裝飾器來修飾其後的myname函式,此時myname函式的參考將傳給第1行myDecorator的參數func,因此func指向myname函式物件。
第2行的wrapper函式宣告一個包裹myname的函式,在第3行先執行myname函式,取得回傳值後將它轉成大寫(對myname函式增加的動作)。
第9行回傳wrapper的參照並由第12行的myname接收,因此myname就指向了wrapper函式物件。以上完成了在不修改myname內容及參照名稱的情況下,增加了原有myname函式的處理。
主程式:
執行結果:
TOMLIN
說明

(2) 使用多個裝飾器
一個函式可以使用多個裝飾器修飾自己,修飾的順序是靠近自己的函式開始,一步步向外套用裝飾器。
以下是一個例子:
第22行的myDecorator2先修飾myname,在回傳值前後加入abc_及_def 文字;接著再套用myDecorator1修飾,將原本文字及新增的文字都轉成大寫。
主程式:
執行結果:
ABC_TOMLIN_XYZ
如果改變裝飾順序:
執行結果:
abc_TOMLIN_xyz
說明:

(3) 接收參數的裝飾器
以下是一個例子:
主程式:
執行結果:
八五〇〇〇
說明:

問題1:
寫一個新台幣裝飾器,名稱是NTdecorator,負責將被修飾函式計算後的數字轉成國字大寫,如12345轉成壹萬貳仟參百肆拾伍元。假設被修飾函式計算後的數字範圍介於0~1000000之間。
問題2:
測試以上程式,試著說明第5行指令的意義。
Last updated