裝飾器 Decorator
加工修飾加上一些我們要的功能
print_fun_name(func) 會把傳入的 function 再利用一個我們命為 wrapper( )的內部function做加工,然後在用 return wrapper 吐出修飾過的 function wrapper,就完成「修飾」的任務
def print_fun_name(func):
def wrapper():
print("runing: ", func.__name__)
func()
return wrapper
def Say():
print("Hi~")
if __name__ == "__main__"
Say = print_fun_name(Say)
Say()
# runing: Say
# Hi~
當有很多function都需要做相同的事情或執行相同的程式碼,就可以用裝飾器來做。
例如:計算時間就很適合使用裝飾器
def print_fun_name(func):
def wrapper():
print("runing: ", func.__name__)
func()
return wrapper
def fun_Timer(func):
def wrapper():
import time
start = time.time()
func()
end = time.time()
print('elapsed', end - start, 'seconds')
return wrapper
def Say():
print("Hi~")
if __name__ == "__main__"
Say = print_fun_name(Say)
Say = fun_Timer(Say)
Say()
# runing: Say
# elapsed 0.00192748472394 seconds
可以直接用@做加裝。syntax candy(語法糖、語法糖衣)。
裝飾器的多層會有順序性,會先合併最靠近的裝飾器,所以會先裝上@fun_Timer在裝上@print_fun_name,因為在第一個@fun_Timer加工後function被包裝為wrapper,所以後面再加裝@print_fun_name後,印出的名稱會為"runing: wrapper"。
def print_fun_name(func):
def wrapper():
print("runing: ", func.__name__)
func()
return wrapper
def fun_Timer(func):
def wrapper():
import time
start = time.time()
func()
end = time.time()
print('elapsed', end - start, 'seconds')
return wrapper
@print_fun_name
@fun_Timer
def Say():
print("Hi~")
if __name__ == "__main__"
Say()
# runing: wrapper
# elapsed 0.00192748472394 seconds
Decorator 的優點:
- 靈活度高
- 易讀性高
- 協助封裝效果好
- 程式碼重複率低/簡潔度高