兩個裝飾器的執行順序
兩個裝飾器的執行順序
如下,兩個裝飾器time_func 和auth_func分別實現了測試程式耗時和認證功能
import time user_name = "zb" user_pwd = "123" def time_func(func1): print("time") def inner1(): print("from inner1") start_time = time.time() func1() stop_time = time.time() print(stop_time-start_time) return inner1 def auth_func(func2): print("auth") def inner2(): print("from inner2") name = input("input your name:").strip() pwd = input("input your password:").strip() if name == user_name and pwd == user_pwd: print("login successful") func2() else: print("name or password error") return inner2 @time_func @auth_func def test(): print("from test") test()
1.python直譯器從上而下執行程式碼:匯入時間模組,定義變數使用者名稱和密碼
2.遇到裝飾器(閉包函式)time_func,申請了1片記憶體地址,函式名time_func指向了這片記憶體地址,程式繼續向下執行(這裡只是定義了函式,並不會執行,所以相當於1行程式碼)
3.遇到裝飾器auth_func,這裡同第2步,申請1片記憶體地址,函式名auth_func 指向這片記憶體地址,程式繼續向下執行
4.直譯器執行到裝飾@time_func這裡,此行程式碼下是一個裝飾器@auth_func而不是一個函式,python直譯器並不會執行裝飾功能,程式繼續向下執行
5.Python直譯器執行到@auth_func,因為裝飾的是一個函式test,定義test函式,申請一片記憶體地址,test指向它
6.裝飾器@auth_func 就相當於test = auth_func(test)
①執行等號左邊程式碼:test賦值給func2即func2指向了test的記憶體地址
②auth_func():執行函式auth_func,定義了函式inner2,申請1片記憶體地址,函式名inner2指向這片記憶體地址(此處並未呼叫函式,故看成1行程式碼),繼續向下執行,返回inner2
③test接收返回值inner2即test指向了inner2的記憶體地址
7.裝飾器@time_func執行,test = time_func(test),
①test賦值給func1即func1指向test的記憶體地址(此時test指向了inner2),故func1指向了inner2,
②定義了函式inner1,申請1片記憶體地址,函式名inner1指向這片記憶體地址(未呼叫函式,故看成1行程式碼),繼續向下執行,返回inner1
③test接收返回值inner1,test指向了inner1的記憶體地址
8.呼叫函式test(),執行test指向的記憶體地址程式碼即inner1,inner1中的func1指向了inner2,inner2中的func2指向了test
inner1()
inner2()
test()
執行結果 inner1,inner2
實際執行結果如下,先裝飾了auth_func,後裝飾了time_func,先執行了計時功能,後執行了驗證功能(此處特地延緩輸入的時間,如果是先執行的驗證功能,此處耗時應該很短)
倒個順序裝飾:耗時0.0s極快
總結:1.靠近函式的先裝飾
2.先裝飾的後執行