Python小程序練習二之裝飾器小例子
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 @timer16 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小程序練習二之裝飾器小例子