Python裝飾器詳情
1、裝飾器
裝飾器(Decorator
):從字面上理解,就是裝飾對象的器件。可以在不修改原有代碼的情況下,為被裝飾的對象增加新的功能或者附加限制條件或者幫助輸出。
裝飾器的特點(diǎn)是特點(diǎn)是函數(shù)是作為其參數(shù)出現(xiàn)的,裝飾器還擁有閉包的特點(diǎn)。
示例代碼如下所示:
# 定義一個裝飾器 def decorate(func): def wrapper(): func() print("已將學(xué)生加入學(xué)校學(xué)生名單") print("已將學(xué)生加入系學(xué)生名單") print("已將學(xué)生加入班級名單") return wrapper @decorate def student(): print("我是小花") student() ''' ---輸出結(jié)果--- 我是小花 已將學(xué)生加入學(xué)校學(xué)生名單 已將學(xué)生加入系學(xué)生名單 已將學(xué)生加入班級名單 '''
使用**@
****符號加函數(shù)名**來裝飾一個函數(shù)
執(zhí)行流程:因?yàn)?code>student是被裝飾的函數(shù),系統(tǒng)將student
函數(shù)以參數(shù)的形式傳入decorate
函數(shù)(裝飾器decorate
),執(zhí)行decorate
函數(shù),并將返回值賦給student
函數(shù)。
上一段代碼等于下面這一段代碼:
# 定義一個裝飾器 def decorate(func): def wrapper(): func() print("已將學(xué)生加入學(xué)校學(xué)生名單") print("已將學(xué)生加入系學(xué)生名單") print("已將學(xué)生加入班級名單") return wrapper def student(): print("我是小花") # 將返回值傳給f 并調(diào)用 f = decorate(student) # 這里不能加(),不然就表示調(diào)用 f() ''' ---輸出結(jié)果--- 我是小花 已將學(xué)生加入學(xué)校學(xué)生名單 已將學(xué)生加入系學(xué)生名單 已將學(xué)生加入班級名單 '''
如果student
函數(shù)外有直接可執(zhí)行的語句,在不調(diào)用student
函數(shù)的情況下,也會被執(zhí)行,
示例代碼如下:
# 定義一個裝飾器 def decorate(func): print("這是外部的代碼") def wrapper(): func() print("已將學(xué)生加入學(xué)校學(xué)生名單") print("已將學(xué)生加入系學(xué)生名單") print("已將學(xué)生加入班級名單") return wrapper @decorate def student(): print("我是小花") # student() ''' ---輸出結(jié)果--- 這是外部的代碼 '''
1.1 應(yīng)用場景
可以用于電商網(wǎng)站的判斷用戶是否登錄來是否繼續(xù)往下執(zhí)行;添加日志等場景,
示例代碼如下所示:
# 定義一個裝飾器 def decorate(func): def wrapper(): func() print("正在檢驗(yàn)用戶是否登錄") # if # 判斷是否登錄的代碼塊 # pass print("用戶已登錄") return wrapper @decorate # 使用裝飾器 def add_shopping_cart(): print("添加成功") @decorate # 使用裝飾器 def payment(): print("付款成功") add_shopping_cart() payment() ''' ---輸出結(jié)果--- 添加成功 正在檢驗(yàn)用戶是否登錄 用戶已登錄 付款成功 正在檢驗(yàn)用戶是否登錄 用戶已登錄 '''
2、萬能裝飾器
因?yàn)楹瘮?shù)的參數(shù)可能是不固定的,所以可以通過函數(shù)的可變參數(shù)來完成這種功能。
示例代碼如下:
def decorate(func): def wrapper(*args, **kwargs): # 使用可變參數(shù)來達(dá)到可以接受任何參數(shù)的效果 print("正在檢測中。。。") print(".............") print("檢測完畢") func(*args, **kwargs) return wrapper @decorate # 使用裝飾器 def f1(): # 無參數(shù) print("這個沒有任何功能") @decorate def f2(name): # 一個參數(shù) print("名字是:", name) @decorate def student(*students): # 多個參數(shù) # *students用于接收多個參數(shù) for ch in students: print(ch) @decorate def student_classroom(*students, classroom="前端班"): # 接收可以賦值的參數(shù) print(f"這是{classroom}的學(xué)生") for ch in students: print(ch) # 調(diào)用函數(shù) f1() ''' ---輸出結(jié)果--- 正在檢測中。。。 ............. 檢測完畢 這個沒有任何功能 ''' f2("一碗周") ''' ---輸出結(jié)果--- 正在檢測中。。。 ............. 檢測完畢 名字是: 一碗周 ''' student("張三", "李四", "王五") ''' ---輸出結(jié)果--- 正在檢測中。。。 ............. 檢測完畢 張三 李四 王五 ''' student_classroom("張三", "李四", "王五", classroom="前端班") ''' 正在檢測中。。。 ............. 檢測完畢 這是前端班的學(xué)生 張三 李四 王五 '''
為了防止錯誤,在定義裝飾器的時候要將其設(shè)置為萬能裝飾器
3、多層裝飾器
多層的執(zhí)行循序執(zhí)行順序是從里到外,最先調(diào)用最里層的裝飾器,最后調(diào)用最外層的裝飾器,
示例代碼如下所示:
def maths(func): # 定義第一個裝飾器 def wrapper(*args, **kwargs): func(*args, **kwargs) print("該學(xué)生已經(jīng)學(xué)習(xí)了數(shù)學(xué)") return wrapper def Chinese(func): # 定義第而個裝飾器 def wrapper(*args, **kwargs): func(*args, **kwargs) print("該學(xué)生已經(jīng)學(xué)習(xí)了語文") return wrapper def English(func): # 定義第三個裝飾器 def wrapper(*args, **kwargs): func(*args, **kwargs) print("該學(xué)生已經(jīng)學(xué)習(xí)了英語") return wrapper @maths @English def student1(name): print(f"學(xué)生{name}已經(jīng)完成了") @English @Chinese @maths def student2(name): print(f"學(xué)生{name}已經(jīng)完成了") # 調(diào)用函數(shù) student1("小明") ''' 學(xué)生小明已經(jīng)完成了 該學(xué)生已經(jīng)學(xué)習(xí)了英語 該學(xué)生已經(jīng)學(xué)習(xí)了數(shù)學(xué) ''' student2("小花") ''' 學(xué)生小花已經(jīng)完成了 該學(xué)生已經(jīng)學(xué)習(xí)了數(shù)學(xué) 該學(xué)生已經(jīng)學(xué)習(xí)了語文 該學(xué)生已經(jīng)學(xué)習(xí)了英語 '''
4、帶參數(shù)的裝飾器
帶參數(shù)的裝飾器一共分為三層,分別如下:
- 第一層:負(fù)責(zé)接收裝飾器的參數(shù)
- 第二層 :負(fù)責(zé)接收函數(shù)
- 第三層:負(fù)責(zé)接收函數(shù)的參數(shù)
示例代碼如下所示:
# 裝飾器帶參數(shù) def outer(a): # 第一層: 負(fù)責(zé)接收裝飾器的參數(shù) def decorate(func): # 第二層 : 負(fù)責(zé)接收函數(shù) def wrapper(*args, **kwargs): # 第三層 負(fù)責(zé)接收函數(shù)的參數(shù) for i in range(a): print(i) func(*args, **kwargs) return wrapper # 返出來的是:第三層 return decorate # 返出來的是:第二層 @outer(3) def number(): print("打印完畢") number() ''' 0 1 2 打印完畢 '''
最外層的函數(shù)負(fù)責(zé)接收裝飾器參數(shù),里面的內(nèi)容還是原裝飾器的內(nèi)容。
到此這篇關(guān)于Python
裝飾器詳情的文章就介紹到這了,更多相關(guān)Python
裝飾器內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python Django獲取URL中的數(shù)據(jù)詳解
這篇文章主要介紹了Python Django獲取URL中的數(shù)據(jù)詳解,小編覺得挺不錯的,這里分享給大家,供需要的朋友參考2021-11-11Python結(jié)巴中文分詞工具使用過程中遇到的問題及解決方法
這篇文章主要介紹了Python結(jié)巴中文分詞工具使用過程中遇到的問題及解決方法,較為詳細(xì)的講述了Python結(jié)巴中文分詞工具的下載、安裝、使用方法及容易出現(xiàn)的問題與相應(yīng)解決方法,需要的朋友可以參考下2017-04-04在Python中使用AOP實(shí)現(xiàn)Redis緩存示例
本篇文章主要介紹了在Python中使用AOP實(shí)現(xiàn)Redis緩存示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-07-07python?使用?with?open()?as?讀寫文件的操作方法
這篇文章主要介紹了python?使用?with?open()as?讀寫文件的操作代碼,寫文件和讀文件是一樣的,唯一區(qū)別是調(diào)用open()函數(shù)時,傳入標(biāo)識符'w'或者'wb'表示寫文本文件或?qū)懚M(jìn)制文件,需要的朋友可以參考下2022-11-11Python 常用日期處理 -- calendar 與 dateutil 模塊的使用
這篇文章主要介紹了Python如何使用calendar 與 dateutil 模塊處理日期,幫助大家更好的理解和學(xué)習(xí)python,感興趣的朋友可以了解下2020-09-09如何通過python實(shí)現(xiàn)IOU計算代碼實(shí)例
這篇文章主要介紹了如何通過python實(shí)現(xiàn)IOU計算代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-11-11python讀取word文檔,插入mysql數(shù)據(jù)庫的示例代碼
今天小編就為大家分享一篇python讀取word文檔,插入mysql數(shù)據(jù)庫的示例代碼,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-11-11