兩個裝飾器的執行順序

兩個裝飾器的執行順序

以下,兩個裝飾器time_func 和auth_func分別實現了測試程序耗時和認證功能python

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解釋器並不會執行裝飾功能,程序繼續向下執行spa

5.Python解釋器執行到@auth_func,由於裝飾的是一個函數test,定義test函數,申請一片內存地址,test指向它 3d

6.裝飾器@auth_func 就至關於test = auth_func(test)code

①執行等號左邊代碼:test賦值給func2即func2指向了test的內存地址blog

②auth_func():執行函數auth_func,定義了函數inner2,申請1片內存地址,函數名inner2指向這片內存地址(此處並未調用函數,故當作1行代碼),繼續向下執行,返回inner2ip

③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.先裝飾的後執行

相關文章
相關標籤/搜索