在說裝飾器前,先說一個東西,再Python裡,有一個 一切皆對象,一切皆變量。
例:
1 def hello(name="sunjinyao"):
2 return "hi " + name
3 print(hello())
4 # 輸出: 'hi sunjinyao'
5 # 我們可以将一個函數指派給一個變量,比如
6 hi = hello
7 # 我們這裡沒有在使用小括号,因為我們并不是在調用hello函數
8 # 而是在将它放在greet變量裡頭。我們嘗試運作下這個
9 print(hi())
10 # 輸出: 'hi sunjinyao'
裝飾器:就是給其他函數添加新功能。本質也是個函數。
原則:1.不修改被裝飾器函數的源代碼2.不修改被裝飾函數的調用方式
裝飾器 = 高階函數 + 函數嵌套 + 閉包
高階函數:函數接收的參數是個函數名或者函數的傳回是一個函數名
函數嵌套:定義的函數内還有函數,一層套一層
閉包:在一個外函數中定義了一個内函數,内函數裡運用了外函數的臨時變量,并且外函數的傳回值是内函數的引用。這樣就構成了一個閉包。
裝飾器架構:
1 #例,變量名随需求更改,這裡隻是例子
2 def login(func):#參數func代表要裝飾的函數
3 def inner(*args,**kwargs):#裝飾器的參數不固定
4 #在這裡添加需要的功能
5 ret = func(*args,**kwargs)
6 #再這裡添加需要的功能
7 return ret
8 return inner #沒有()沒有執行
例:為TEST函數寫一個裝飾器,統計TEST函數的運作時間
1 #為TEST函數寫一個裝飾器,統計TEST函數的運作時間
2 import time #導入時間子產品
3 def time_1(func):#func = my_test
4 def inner():
5 start_time = time.time()
6 ret = func()
7 stop_time = time.time()
8 print('函數的運作時間為%s'%(stop_time-start_time))
9 return ret
10 return inner
11 @time_1 #必須在所裝飾的函數前使用。
12 #@time_1 == my_test = time_1(my_test)
13 def my_test():
14 time.sleep(3)
15 print('test函數運作完畢')
16 return '這個是my_test的執行結果'
17 #my_test = time_1(my_test)
18 #time_1(my_test) 相當inner函數記憶體位址 因為time1的reture結果是inner
19 print(my_test())#執行了inner函數
練一練:#編寫裝飾器,為多個函數加上認證功能(使用者密碼來源于檔案),要求登入一次,後續函數無需再輸入密碼。輸入的密碼為3次。
例:檔案内容
abc,123
def,456
1 login_status = False
2 def login(func):
3 def inner(*args,**kwargs):
4 global login_status
5 if not login_status:
6 count = 0
7 while count < 3:
8 user_name =input('請輸入使用者名:')
9 pass_word =input('請輸入密碼:')
10 with open('my_file',encoding='utf8') as passwd_file:
11 for line in passwd_file:
12 login_name,login_pwd = line.strip().split(',')
13 #用,号分割賬号密碼并指派,檔案末尾都是有換行的,去掉空格(strip在前)
14 if user_name == login_name and pass_word == login_pwd:
15 login_status = True
16 print('登入成功')
17 count += 3 #為了跳出while循環
18 ret = func(*args, **kwargs)
19 return ret#跳出了for循環
20 else:
21 print('登入失敗,請重新登入')
22 count += 1
23 break
24 elif login_status:#在上面循環中,把Login_status狀态改成 True之後,就不需要再次輸入密碼
25 ret = func(*args, **kwargs)
26 return ret
27 return inner
28 @login
29 def shopping_web():
30 return '購物界面'
31 @login
32 def home_web():
33 return '個人中心'
34 shopping_web()
35 home_web()
36 print(home_web())
37 print(shopping_web())
38 print(home_web())
轉載于:https://www.cnblogs.com/sunjinchao/p/10896893.html