您好,登錄后才能下訂單哦!
本文實例講述了Python裝飾器原理與用法。分享給大家供大家參考,具體如下:
1、裝飾器的本質是函數,主要用來裝飾其他函數,也就是為其他函數添加附加功能
2、裝飾器的原則:
(1) 裝飾器不能修改被裝飾的函數的源代碼
(2) 裝飾器不能修改被裝飾的函數的調用方式
3、實現裝飾器的知識儲備
(1) Python中函數即‘變量'
a、變量在Python中的存儲
x='Tomwenxing' y=x
[說明]:
當Python解釋器遇到語句x='Tomwenxing'時,它主要完成了兩樣工作:
1.在內存中開辟了一片空間用來存儲字符串‘Tomwenxing'
2.在內存從創建了一個名為x的變量,并用它指向字符串‘Tomwenxing'所占據的內存空間(可以理解為房間和房間號的關系)
而語句y=x意為將變量x對字符串的引用賦值給變量y,即在內存中創建一個變量y,并使其指向變量x所指向的內存空間
b、函數在Python中的存儲
def test(): pass
[說明]:
在Python中,函數的存儲和變量相似,以上面的函數為例,Python解釋其主要做兩件事:
1.在內存中開辟一個內存空間,用來存儲函數代碼的字符串(本例中代碼只有一句:pass)
2.在內存中創建一個變量test,用來指向存儲函數代碼字符串的內存空間(相當于test=‘函數體')
因此說在Python中函數即變量
(2) 高階函數(下面兩個條件滿足任何一個即為高階函數)
a、把一個函數名當做實參傳遞給另外一個函數
[對裝飾器的影響]:達到“在不修改被裝飾函數源代碼的情況下為其添加功能”的效果
import time def bar(): time.sleep(2) print('in the bar') def test(func): start_time=time.time() func() stop_time=time.time() print('函數的運行時間為:',stop_time-start_time) test(bar)
運行結果:
in the bar
函數的運行時間為: 2.0021145343780518
b、返回值中包含函數名
[對裝飾器的影響]:達到“不改變函數的調用方式“的效果
import time def bar(): time.sleep(3) print('in the bar') def test2(func): print('新添加的功能') return func bar=test2(bar) bar()
運行結果:
新添加的功能
in the bar
(3) 嵌套函數:在一個函數體內用def去聲明一個新的函數(不是調用)
def foo(): print('in the foo') def bar(): #聲明一個新的函數,而不是調用函數 print('in the bar') bar() foo()
運行結果:
in the foo
in the bar
4、裝飾器的語法:高階函數+嵌套函數=》裝飾器 (下面的例子可以用pycharm的調試器調試一下,看看代碼的運行順序)
import time def timer(func): def deco(*args,**kwargs):#使用了不定參數 start_time=time.time() res=func(*args,**kwargs) #運行函數 stop_time=time.time() print('運行時間:',stop_time-start_time) return res # 若無返回值,則返回None return deco @timer #等價于test1=timer(test1)=deco,即test1()=deco() def test1(): time.sleep(3) print('in the test1') @timer #等價于test2=timer(test2)=deco,即test2(name)=deco(name) def test2(name): time.sleep(3) print('in the test2',name) test1() print('-------------分界線------------------------') test2('Tomwenxing')
運行結果:
in the test1
運行時間: 3.0001718997955322
-------------分界線------------------------
in the test2 Tomwenxing
運行時間: 3.000171422958374
5、帶參數的裝飾器
# -*- coding:utf-8 -*- user,passwd='Tomwenxing','123' #如裝飾器帶參數,一般是三層嵌套 def auth(auth_type): #第一層的參數是裝飾器的參數 def outer_wrapper(func):#第二層的參數是裝飾器要裝飾的目標函數 def wrapper(*args,**kwargs):#第三次的參數是目標函數的參數 if auth_type=='local': username = input('Username:').strip() password = input('Password:').strip() if user == username and passwd == password: print('用戶Tomwenxing已經成功登錄!') res = func(*args, **kwargs) #運行目標函數 return res else: exit('用戶名或密碼有錯誤') elif auth_type=='ldap': print('暫不支持這種登錄方式!') return wrapper return outer_wrapper def index(): print('歡迎來到index頁面') @auth(auth_type='local') #home=wrapper() def home(name): print('%s,歡迎來到home頁面' %name) return 'This is home page' @auth(auth_type='ldap') def bbs(): print('歡迎來到bbs頁面 ') index() print('----------------------分界線-------------------') print('函數的返回值為:',home('wenxing')) print('----------------------分界線-------------------') bbs()
運行結果:
歡迎來到index頁面
----------------------分界線-------------------
Username:Tomwenxing
Password:123
用戶Tomwenxing已經成功登錄!
wenxing,歡迎來到home頁面
函數的返回值為: This is home page
----------------------分界線-------------------
暫不支持這種登錄方式!
更多關于Python相關內容感興趣的讀者可查看本站專題:《Python數據結構與算法教程》、《Python加密解密算法與技巧總結》、《Python編碼操作技巧總結》、《Python函數使用技巧總結》、《Python字符串操作技巧匯總》及《Python入門與進階經典教程》
希望本文所述對大家Python程序設計有所幫助。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。