裝飾器
裝飾器是用來處理其他函式的函式,主要作用是在不修改原有函式的情況下新增新的功能,裝飾器的返回值也是一個函式物件。
簡單的裝飾器
1 import time 2 3 def show_time(f): 4 def inner(): 5 start = time.time() 6 f() 7 end = time.time() 8 print(`time: %s`%(end-start)) 9 return inner 10 11 @show_time 12 def fun1(): 13 print(`hello`) 14 time.sleep(1) 15 16 fun1()
#輸出
#hello
#time: 1.000274896621704
其中@show_time的意思是 fun1 = showtime(fun1) ,作用是在執行原函式add()時,把執行的程式碼轉為inner()函式中的程式碼。
帶引數的被裝飾函式
如果被裝飾的函式帶有引數則裝飾函式要帶上引數。
引數個數確定時:
1 import time 2 3 def show_time(f): 4 def inner(a,b): 5 start = time.time() 6 f(a,b) 7 end = time.time() 8 print(`time: %s`%(end-start)) 9 return inner 10 11 @show_time 12 def fun1(x,y): 13 print(x+y) 14 time.sleep(1) 15 16 fun1(1,2)
#輸出
#3
#time: 1.0007870197296143
引數個數不確定時:
1 import time 2 3 def show_time(f): 4 def inner(*args,**kwargs): 5 start = time.time() 6 f(*args,**kwargs) 7 end = time.time() 8 print(`time: %s`%(end-start)) 9 return inner 10 11 @show_time 12 def fun1(*args,**kwargs): 13 sum = 0 14 for i in args: 15 sum+=i 16 print(sum) 17 time.sleep(1) 18 19 fun1(1,2,3,4,5)
#輸出
#15
#time: 1.0009024143218994
帶引數的裝飾器
import time def judge(flag = `False`): def show_time(f): def inner(*args,**kwargs): if flag == `True`: start = time.time() f(*args,**kwargs) end = time.time() print(`time: %s`%(end-start)) else: f(*args, **kwargs) return inner return show_time @judge(`True`) def add(*args,**kwargs): sum = 0 for i in args: sum+=i print(sum) time.sleep(1) @judge() def multiple(*args,**kwargs): sum = args[0] for i in args: sum*=i print(sum) time.sleep(1) add(1,2,3,4,5) multiple(1,2,3,4,5)
#輸出
#15
#time: 1.0006871223449707
#120
裝飾器的語法允許我們在呼叫時,提供其它引數,比如當@judge()引數為預設的False時,不輸出消耗時間了,當@judge()引數為True時,輸出了消耗時間。這樣實際上是在原有的裝飾器上再加了一層,當我 們使用@judge(‘True’)呼叫的時候,Python能夠發現這一層的封裝,並把引數傳遞到裝飾器的環境中。