1. 程式人生 > >Python小程序練習二之裝飾器小例子

Python小程序練習二之裝飾器小例子

現實 none align style args ldap .net dad 現在

Python小程序練習二之裝飾器小例子

裝飾器:

裝飾器實際上就是為了給某程序增添功能,但該程序已經上線或已經被使用,那麽就不能大批量的修改源代碼,這樣是不科學的也是不現實的,因為就產生了裝飾器,使得其滿足:

1、不能修改被裝飾的函數的源代碼

2、不能修改被裝飾的函數的調用方式

那麽根據需求,同時滿足了這兩點原則,這才是我們的目的。

裝飾器的原則組成:

< 函數+實參高階函數+返回值高階函數+嵌套函數+語法糖 = 裝飾器 >

錯誤例子:

1、1Decorators.py

技術分享圖片
 1 # The author is tou
2 # Version:Python 3.6.5 3 import time 4 5 def timer(func): 6 start_time = time.time() 7 func() 8 stop_time = time.time() 9 print("The func run time is :",(stop_time-start_time)) 10 11 @timer 12 def test1(): 13 time.sleep(1) #停1秒打印 14 print("This is test1") 15 @timer
16 def test2(): 17 time.sleep(1) #停1秒打印 18 print("This is test2") 19 #test1() 20 #test2()
錯誤例子

技術分享圖片

你會發現當不調用test1()和test2()時,程序正常運行,調用test1()和test2()時便會出現TypeError: ‘NoneType‘ object is not callable(對象不可調用)的錯誤,該程序只用了函數+實參高階函數,並沒有用到返回值高階函數和嵌套函數。

正確例子

2、2Decorators.py

技術分享圖片
 1 # The author is tou
2 # Version:Python 3.6.5 3 import time 4 5 def timer(func): 6 def dooc(): 7 start_time = time.time() 8 func() 9 stop_time = time.time() 10 print("The func run time is :",(stop_time-start_time)) 11 return dooc 12 13 #@timer 14 def test1(): 15 time.sleep(1) #停1秒打印 16 print("This is test1") 17 test1 = timer(test1) 18 @timer 19 def test2(): 20 time.sleep(1) #停1秒打印 21 print("This is test2") 22 test1() 23 test2()
正確例子

技術分享圖片

  裝飾器在裝飾時,需要在每個函數前面加上:@timer這是Python提供的一種語法糖

  其實它和 test1 = timer(test1) 是等價的,只要在函數前加上這句,就可以實現裝飾作用。test1()和test2()的運行效果是一樣的

3、3Decorators.py

當調用函數需要傳遞參數時,timer函數就不能滿足要求,可修改為一下形式。使其對傳不傳參數都可以使用裝飾器。

技術分享圖片
 1 # The author is tou
 2 # Version:Python 3.6.5
 3 import time
 4 
 5 def timer(func):
 6     def dooc(*args,**kwargs):
 7         start_time = time.time()
 8         func(*args,**kwargs)
 9         stop_time = time.time()
10         print("The func run time is :", (stop_time - start_time))
11     return dooc
12 
13 @timer
14 def test1():
15     time.sleep(1)  # 停1秒打印
16     print("This is test1")
17 
18 @timer
19 def test2(name):
20     time.sleep(1)  # 停1秒打印
21     print("This is %s"%name)
22 
23 test1()
24 test2("tou")
帶參數的裝飾器

技術分享圖片

最後,通過一個需求來練習一下裝飾器

現在有一個網站,首頁不需要登陸,自己主頁和BBS需要登陸,並且主頁和BBS登陸方式不一樣,主頁采取local方式,BBS采用ldap方式。我們使用一個函數代表一個頁面。

4、4Decorators.py

技術分享圖片
 1 # The author is tou
 2 # Version:Python 3.6.5
 3 user_name,user_password = "tou","123456"
 4 
 5 def request(request_type):
 6     def type(func):
 7         def dooc(*args,**kwargs):
 8             if request_type == "local":
 9                 name = input("請輸入您的用戶名:").strip()
10                 password = input("請輸入您的密碼:").strip()
11                 if name == user_name and password == user_password:
12                     print("\033[32;1m登陸成功!\033[0m")
13                     res = func(*args,**kwargs)
14                     return res
15                 else:
16                     exit("您輸入的用戶名或者密碼錯誤!")
17             else:
18                 print("\033[31;1m沒有這種登陸方式\033[0m")
19         return dooc
20     return type
21 
22 def index():
23     print("歡迎進入首頁")
24 @request(request_type = "local")
25 def home():
26     print("歡迎進入您的主頁")
27     return "來自home"
28 @request(request_type = "ldap")
29 def BBS():
30     print("歡迎進入BBS主頁")
31 
32 index()
33 print(home())
34 BBS()
網站登錄小練習 技術分享圖片 在此,裝飾器的小練習便結束了

Python小程序練習二之裝飾器小例子