Python之實戰裝飾器拆解
阿新 • • 發佈:2019-01-04
實現裝飾器需要具備那些知識:
1.函式既”變數” 屬於可變化資料
函式是無關順序的,但是執行呼叫的函式必須在執行程式碼前面
示例:
變數:
a=[1,2] #a為變數名,[1,2]存放記憶體裡面 ==專業稱之變數體
函式:
def test1(): ..... #test1==該函式的名字(如變數名a) #():內的程式碼 == [1,2]存放在記憶體裡面 ==專業稱之函式體 #注意1:test1獲取該函式的記憶體地址 、test1+ ()==執行該test1函式 #注意2:變數體(函式體)必須最少擁有一個變數名(函式名),否則記憶體回收
2.高階函式
a:把一個函式名當做實參傳給另外一個函式的函式:
通過實驗得到:在不修改被裝飾函式原始碼的情況下為其添加了功能
b:返回值中包含函式名
通過實驗得到:不修改函式的呼叫方式和原始碼也可以新增功能
示例:
import time def bar(): time.sleep(3) print('in the bar') def test2(func): print(func) return func test2(bar)() #bar獲取的是函式bar函式的記憶體地址 #bar()才是執行該函式
3.巢狀函式
高階函式+巢狀函式=裝飾器
示例:
import time def timmer(func): def warpper(*args,**kwargs): start_time = time.time()#開始時間 func()#呼叫開始時間(該裝飾我還不清楚,目前這樣解釋) stop_time = time.time()#結束時間 print('the func run time is %s' %(stop_time-start_time))#列印顯示xxx開始時間- return warpper def test(): time.sleep(3)#間隔3秒,也就是被呼叫了執行到該步驟的時候停3秒,繼續往下操作 print('in the test') a=timmer(test) # a == warpper a() # a()==warpper() #timmer(test)() == warpper()等於上面兩條命令
詳解:
- timmer(test1)得到的是warpper的該函式記憶體地址
- timmer(func) func=test該函式體
- 賦值a a() ==warpper()
- 全域性變數和區域性變數規則,意味著warpper()可以呼叫timmer函式的形參func
- 最終執行了func() == test()
timmer函式符合高階函式,和巢狀函式,所以是裝飾器
經過Python優化以後裝飾器呼叫變成如下:
@timmer裝飾到指定的函式如def test1()上面:
import time
def timmer(func):
def warpper(*args,**kwargs):
start_time = time.time()#開始時間
func()#呼叫開始時間(該裝飾我還不清楚,目前這樣解釋)
stop_time = time.time()#結束時間
print('the func run time is %s' %(stop_time-start_time))#列印顯示xxx開始時間-
return warpper
@timmer#呼叫裝飾器,在需要裝飾的函式的上方
def test():
time.sleep(3)#間隔3秒,也就是被呼叫了執行到該步驟的時候停3秒,繼續往下操作
print('in the test')
test()
#帶裝飾器和正常寫法的轉換:
#func = test
#test = timmer(test) == warpper
#test()=timmer(test)() == warpper()
test該函式有形參怎麼辦?
1.我們知道func = test
2.timmer(test1)得到的是warpper的該函式記憶體地址賦值到test
3.test() == warpper()
4. warpper函式增加引數組(元祖和字典)
5. test(1,2) == warpper(1,2) warpper函式執行func的時候在把形參給func就OK了fun(1,2)
示例:
import time
def timmer(func):
def warpper(*args,**kwargs):
start_time = time.time()#開始時間
func(args[0], args[1])#呼叫開始時間(該裝飾我還不清楚,目前這樣解釋)
stop_time = time.time()#結束時間
print('the func run time is %s' %(stop_time-start_time))#列印顯示xxx開始時間-
return warpper
@timmer#呼叫裝飾器,在需要裝飾的函式的上方
def test(a,b):
time.sleep(3)#間隔3秒,也就是被呼叫了執行到該步驟的時候停3秒,繼續往下操作
print('in the test')
test(1,2)
#帶裝飾器和正常寫法的轉換:
#func = test
#test = timmer(test) == warpper
#test1(1,2)=timmer(test)(1,2) == warpper(1,2)
# func(args[0], args[1]) == test(1,2)
test該函式有return怎麼辦?
示例:
import time
def timmer(func):
def warpper(*args,**kwargs):
start_time = time.time()#開始時間
res = func(args[0], args[1])#呼叫開始時間(該裝飾我還不清楚,目前這樣解釋)
stop_time = time.time()#結束時間
print('the func run time is %s' %(stop_time-start_time))#列印顯示xxx開始時間-
return res
return warpper
@timmer#呼叫裝飾器,在需要裝飾的函式的上方
def test(a,b):
time.sleep(3)#間隔3秒,也就是被呼叫了執行到該步驟的時候停3秒,繼續往下操作
return 1
res = test(1,2)
高階裝飾器(其實都是一樣)