1. 程式人生 > 其它 >Python函式直譯器進階(三)

Python函式直譯器進階(三)

一.裝飾器的簡易版本

 1 # 裝飾器簡易版本
 2 def index():
 3     time.sleep(3)
 4     print('哈哈哈哈')
 5 import time
 6 def outer(func):
 7     def get_time():
 8         start_time = time.time()
 9         func()
10         end_time = time.time()
11         print('函式運行了%s' % (end_time - start_time))
12     return get_time
13 index = outer(index) 14 index()

二.解決引數問題

 1 # 解決引數問題
 2 import time
 3 def index():
 4     time.sleep(3)
 5     print('哈哈哈哈')
 6 def login(name):
 7     time.sleep(1)
 8     print('使用者%s輸入成功' % name)
 9 def outer(func):
10     def get_time(*args, **kwargs):
11         start_time = time.time()
12 func(*args, **kwargs) 13 end_time = time.time() 14 print('函式執行時間%s' % (end_time - start_time)) 15 return get_time 16 index = outer(index) 17 index() 18 login = outer(login) 19 login('jack')

三.解決函式返回值問題

 1 import time
 2 def login(name):
 3     time.sleep(1)
 4     print
('使用者%s輸入成功' % name) 5 return 'from login' 6 def outer(func): # func指向的是函式名login 7 # func = login 8 def get_time(*args,**kwargs): 9 start_time = time.time() 10 res = func(*args,**kwargs) # 接收被裝飾函式的返回值 11 end_time = time.time() 12 print('函式執行時間:%s' % (end_time - start_time)) 13 return res # 執行完get_time之後返回被裝飾函式執行之後的返回值 14 return get_time # 將get_time函式名返回出去 15 login = outer(login) 16 res1 = login('jason') 17 print(res1)

四.認證裝飾器

 1 # 定義一個用於記錄使用者資料是否登入的資料
 2 is_login = {'is_login': False}
 3 import time
 4 def index():
 5     time.sleep(1)
 6     print('恭喜你中獎了')
 7 def study():
 8     time.sleep(2)
 9     print('學習不是一天完成的事情,要堅持不懈')
10 def register():
11     time.sleep(3)
12     print('註冊功能')
13 def login_auth(func):
14     def auth(*args, **kwargs):
15         # 判斷使用者是否已經登入
16         if is_login.get('is_login'):
17             res = func(*args, **kwargs)
18             # 登入的話直接執行函式
19             return res
20         username = input('請輸入使用者名稱').strip()
21         password = input('請輸入密碼').strip()
22         # 判斷登入賬號是否正確
23         if username == 'jason' and password == '123':
24             # 正常執行函式
25             res = func()
26             # 將記錄使用者狀態的資料修改
27             is_login['is_login'] = True
28             return res
29         else:
30             print('使用者名稱或者密碼錯誤')
31     return auth
32 index=login_auth(index)
33 index()
34 study=login_auth(study)
35 study()
36 register=login_auth(register)
37 register()

先登入賬號,賬號正確的話後面兩個函式自動執行

五.裝飾器固定模板

這個模板,寫程式碼時可以直接使用

def outer(func):
    def inner(*args, **kwargs):
        print('執行函式之前可以新增的額外功能')
        res = func(*args, **kwargs)  # 執行被裝飾的函式
        print('執行函式之後可以新增的額外功能')
        return res  # 將被裝飾函式執行之後的返回值返回
    return inner

六.裝飾器語法糖

 1 def outer(func):
 2     def inner(*args, **kwargs):
 3         print('執行函式之前可以新增的額外功能')
 4         res = func(*args, **kwargs)  # 執行被裝飾的函式
 5         print('執行函式之後可以新增的額外功能')
 6         return res  # 將被裝飾函式執行之後的返回值返回
 7     return inner
 8 @outer  # index = outer(index)
 9 def index(*args, **kwargs):
10     print('from index')
11 @outer  # home = outer(home)
12 def home():
13     print('from home')

裝飾器語法糖書寫規範

語法糖必須緊貼在被裝飾函式的上方

裝飾器語法糖內部原理

會自動將下面緊貼著的被裝飾物件名字當做引數傳給裝飾器函式呼叫

七.裝飾器修復技術

 1 from functools import wraps
 2 def outer(func):
 3     @wraps(func)  # 修復技術就是為了讓被裝飾物件更加不容易被察覺裝飾了
 4     def inner(*args, **kwargs):
 5         print('執行函式之前可以新增的額外功能')
 6         res = func(*args, **kwargs)  # 執行被裝飾的函式
 7         print('執行函式之後可以新增的額外功能')
 8         return res  # 將被裝飾函式執行之後的返回值返回
 9     return inner
10 
11 
12 @outer  # index = outer(index)
13 def index():
14     print('from index')
15 print(index)
16 help(index)
17 
18 def home():
19     """這是一個home函式"""
20     print('from home')
21 # help(index)
22 # help(home)
23 # print(index)
24 # help(len)

八.有參裝飾器

 1 def outer(source_data):
 2     # source_data = 'file'
 3     def login_auth(func):
 4         def auth(*args,**kwargs):
 5             # 2.校驗使用者名稱和密碼是否正確
 6             # 資料的校驗方式可以切換多種
 7             if source_data == 'file':
 8                 # 從檔案中獲取使用者資料並比對
 9                 print('file檔案獲取')
10             elif source_data == 'MySQL':
11                 # 從MySQL資料庫中獲取資料比對
12                 print('MySQL資料庫獲取')
13             elif source_data == 'postgreSQL':
14                 # 從postgreSQL資料庫中獲取資料對比
15                 print('postgreSQL資料庫獲取')
16             else:
17                 print('使用者名稱或密碼錯誤 無法執行函式')
18         return auth
19     return login_auth
20 
21 @outer('file')
22 def index():
23     print('from index')
24 @outer('MySQL')
25 def home():
26     print('from home')
27 
28 index()
29 home()