Python裝飾器詳情
1、裝飾器
裝飾器(Decorator
):從字面上理解,就是裝飾對象的器件。可以在不修改原有代碼的情況下,為被裝飾的對象增加新的功能或者附加限制條件或者幫助輸出。
裝飾器的特點是特點是函數是作為其參數出現的,裝飾器還擁有閉包的特點。
示例代碼如下所示:
# 定義一個裝飾器 def decorate(func): def wrapper(): func() print("已將學生加入學校學生名單") print("已將學生加入系學生名單") print("已將學生加入班級名單") return wrapper @decorate def student(): print("我是小花") student() ''' ---輸出結果--- 我是小花 已將學生加入學校學生名單 已將學生加入系學生名單 已將學生加入班級名單 '''
使用**@
****符號加函數名**來裝飾一個函數
執行流程:因為student
是被裝飾的函數,系統將student
函數以參數的形式傳入decorate
函數(裝飾器decorate
),執行decorate
函數,並將返回值賦給student
函數。
上一段代碼等於下面這一段代碼:
# 定義一個裝飾器 def decorate(func): def wrapper(): func() print("已將學生加入學校學生名單") print("已將學生加入系學生名單") print("已將學生加入班級名單") return wrapper def student(): print("我是小花") # 將返回值傳給f 並調用 f = decorate(student) # 這裡不能加(),不然就表示調用 f() ''' ---輸出結果--- 我是小花 已將學生加入學校學生名單 已將學生加入系學生名單 已將學生加入班級名單 '''
如果student
函數外有直接可執行的語句,在不調用student
函數的情況下,也會被執行,
示例代碼如下:
# 定義一個裝飾器 def decorate(func): print("這是外部的代碼") def wrapper(): func() print("已將學生加入學校學生名單") print("已將學生加入系學生名單") print("已將學生加入班級名單") return wrapper @decorate def student(): print("我是小花") # student() ''' ---輸出結果--- 這是外部的代碼 '''
1.1 應用場景
可以用於電商網站的判斷用戶是否登錄來是否繼續往下執行;添加日志等場景,
示例代碼如下所示:
# 定義一個裝飾器 def decorate(func): def wrapper(): func() print("正在檢驗用戶是否登錄") # if # 判斷是否登錄的代碼塊 # pass print("用戶已登錄") return wrapper @decorate # 使用裝飾器 def add_shopping_cart(): print("添加成功") @decorate # 使用裝飾器 def payment(): print("付款成功") add_shopping_cart() payment() ''' ---輸出結果--- 添加成功 正在檢驗用戶是否登錄 用戶已登錄 付款成功 正在檢驗用戶是否登錄 用戶已登錄 '''
2、萬能裝飾器
因為函數的參數可能是不固定的,所以可以通過函數的可變參數來完成這種功能。
示例代碼如下:
def decorate(func): def wrapper(*args, **kwargs): # 使用可變參數來達到可以接受任何參數的效果 print("正在檢測中。。。") print(".............") print("檢測完畢") func(*args, **kwargs) return wrapper @decorate # 使用裝飾器 def f1(): # 無參數 print("這個沒有任何功能") @decorate def f2(name): # 一個參數 print("名字是:", name) @decorate def student(*students): # 多個參數 # *students用於接收多個參數 for ch in students: print(ch) @decorate def student_classroom(*students, classroom="前端班"): # 接收可以賦值的參數 print(f"這是{classroom}的學生") for ch in students: print(ch) # 調用函數 f1() ''' ---輸出結果--- 正在檢測中。。。 ............. 檢測完畢 這個沒有任何功能 ''' f2("一碗周") ''' ---輸出結果--- 正在檢測中。。。 ............. 檢測完畢 名字是: 一碗周 ''' student("張三", "李四", "王五") ''' ---輸出結果--- 正在檢測中。。。 ............. 檢測完畢 張三 李四 王五 ''' student_classroom("張三", "李四", "王五", classroom="前端班") ''' 正在檢測中。。。 ............. 檢測完畢 這是前端班的學生 張三 李四 王五 '''
為瞭防止錯誤,在定義裝飾器的時候要將其設置為萬能裝飾器
3、多層裝飾器
多層的執行循序執行順序是從裡到外,最先調用最裡層的裝飾器,最後調用最外層的裝飾器,
示例代碼如下所示:
def maths(func): # 定義第一個裝飾器 def wrapper(*args, **kwargs): func(*args, **kwargs) print("該學生已經學習瞭數學") return wrapper def Chinese(func): # 定義第而個裝飾器 def wrapper(*args, **kwargs): func(*args, **kwargs) print("該學生已經學習瞭語文") return wrapper def English(func): # 定義第三個裝飾器 def wrapper(*args, **kwargs): func(*args, **kwargs) print("該學生已經學習瞭英語") return wrapper @maths @English def student1(name): print(f"學生{name}已經完成瞭") @English @Chinese @maths def student2(name): print(f"學生{name}已經完成瞭") # 調用函數 student1("小明") ''' 學生小明已經完成瞭 該學生已經學習瞭英語 該學生已經學習瞭數學 ''' student2("小花") ''' 學生小花已經完成瞭 該學生已經學習瞭數學 該學生已經學習瞭語文 該學生已經學習瞭英語 '''
4、帶參數的裝飾器
帶參數的裝飾器一共分為三層,分別如下:
- 第一層:負責接收裝飾器的參數
- 第二層 :負責接收函數
- 第三層:負責接收函數的參數
示例代碼如下所示:
# 裝飾器帶參數 def outer(a): # 第一層: 負責接收裝飾器的參數 def decorate(func): # 第二層 : 負責接收函數 def wrapper(*args, **kwargs): # 第三層 負責接收函數的參數 for i in range(a): print(i) func(*args, **kwargs) return wrapper # 返出來的是:第三層 return decorate # 返出來的是:第二層 @outer(3) def number(): print("打印完畢") number() ''' 0 1 2 打印完畢 '''
最外層的函數負責接收裝飾器參數,裡面的內容還是原裝飾器的內容。
到此這篇關於Python
裝飾器詳情的文章就介紹到這瞭,更多相關Python
裝飾器內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!