Python?Decorator裝飾器的創(chuàng)建方法及常用場景分析
前言
1.裝飾器本質(zhì)是一個語法糖,是對被裝飾方法或類進行的功能擴充,是一種面向切面的實現(xiàn)方法
2.裝飾器可以分成方法裝飾器和類裝飾器,他們的區(qū)別是一個是用函數(shù)實現(xiàn)的裝飾器,一個是用類實現(xiàn)的裝飾器,他們也都能在方法和類上進行裝飾
3.類裝飾器看起來結(jié)構(gòu)更加清晰,因此下面的代碼實現(xiàn)的裝飾器全是類裝飾器
一、創(chuàng)建方式
1.創(chuàng)建“裝飾方法”的類裝飾器
from functools import wraps # 裝飾器類 class MyDecorator(object): def __init__(self, plusNum): self.plusNum = plusNum # 裝飾器入?yún)? def __call__(self, func): @wraps(func) # @wraps保證裝飾器不改變被裝飾方法的原有函數(shù)結(jié)構(gòu) def wrapped_function(*args, **kwargs): # 調(diào)用被裝飾方法前執(zhí)行一些操作 --------------- # 如果不加@wraps,此處打印結(jié)果將是 funcName = func.__name__ print("funcName: {}".format(funcName)) # --------------------------------------- # 修改被裝飾方法的入?yún)?-- num1 = args[0] + 2 num2 = args[1] + 3 args = (num1, num2) # ------------------- # 執(zhí)行被裝飾方法 ------------- res = func(*args, **kwargs) # ------------------------- # 調(diào)用被裝飾方法后執(zhí)行一些操作 ------------- print("do something after the func...") # ------------------------------------- # 修改被裝飾方法的出參 -- res += self.plusNum # ------------------- # 返回被裝飾方法的參數(shù) return res # 返回裝飾器方法 return wrapped_function # 被裝飾的方法 @MyDecorator(3) def add(num1, num2): return num1+num2 if __name__ == '__main__': # 整體執(zhí)行流程: # 1. 打印 add 方法名 # 2. 修改被裝飾方法入?yún)? # 3. 執(zhí)行被裝飾方法 # 4. 調(diào)用被裝飾方法后執(zhí)行一些操作 # 5. 修改被裝飾方法的出參 # 6. 打印結(jié)果 print(add(5, 3)) # funcName: add # do something after the func... # 16
2.創(chuàng)建“裝飾類中方法”的類裝飾器
from functools import wraps # 裝飾器類 class MyDecorator(object): def __init__(self, plusNum): self.plusNum = plusNum # 裝飾器入?yún)? def __call__(self, func): @wraps(func) # @wraps保證裝飾器不改變被裝飾方法的原有函數(shù)結(jié)構(gòu) def wrapped_function(*args, **kwargs): # 此處與直接裝飾方法相同 # 調(diào)用被裝飾方法前執(zhí)行一些操作 --------------- # 如果不加@wraps,此處打印結(jié)果將是 funcName = func.__name__ print("funcName: {}".format(funcName)) # --------------------------------------- # 此處需要注意,如果需要修改入?yún)⒌闹?,那么傳參的索引是?開始而不是從0開始,因為第一個入?yún)⒌闹凳菍嵗旧韘elf # 修改被裝飾方法的入?yún)?-- num1 = args[1] + 2 num2 = args[2] + 3 args = (args[0], num1, num2) # ------------------- # 此處與直接裝飾方法相同 # 執(zhí)行被裝飾方法 ------------- res = func(*args, **kwargs) # ------------------------- # 此處與直接裝飾方法相同 # 調(diào)用被裝飾方法后執(zhí)行一些操作 ------------- print("do something after the func...") # ------------------------------------- # 此處與直接裝飾方法相同 # 修改被裝飾方法的出參 -- res += self.plusNum # ------------------- # 返回被裝飾方法的參數(shù) return res # 返回裝飾器方法 return wrapped_function class Operation(object): # 被裝飾的類方法 @MyDecorator(3) def add(self, num1, num2): return num1+num2 if __name__ == '__main__': op = Operation() print(op.add(3, 5)) # funcName: add # do something after the func... # 16
3.創(chuàng)建“裝飾類”的類裝飾器
from functools import wraps # 裝飾器類 class MyDecorator(object): def __init__(self, plusNum): self.plusNum = plusNum # 裝飾器入?yún)? def __call__(self, Cls): @wraps(Cls) # @wraps保證裝飾器不改變被裝飾類的原有結(jié)構(gòu) def wrapped_function(*args, **kwargs): # 調(diào)用被裝飾類前執(zhí)行一些操作 --------------- # 如果不加@wraps,此處打印結(jié)果將是 clsName = Cls.__name__ print("clsName: {}".format(clsName)) # --------------------------------------- # 修改被裝飾類的入?yún)?--- num1 = args[0] + 2 num2 = args[1] + 3 args = (num1, num2) # ------------------- # 初始化被裝飾類 ------------- cls = Cls(*args, **kwargs) # ------------------------- # 初始化后執(zhí)行一些操作 -------------------- print("do something after the func...") # ------------------------------------- # 給類實例增加增加屬性和方法 --------------------- cls.mul = 3 # 增加屬性 cls.plusNumber = self.plusNumber # 增加方法 # ------------------------------------------- # 返回實例 return cls # 返回裝飾器方法 return wrapped_function def plusNumber(self, num): return num + self.plusNum # 被裝飾的類 @MyDecorator(3) class Operation(object): def __init__(self, num1, num2): self.num1 = num1 self.num2 = num2 def add(self): num3 = self.num1 + self.num2 num4 = self.plusNumber(num3*self.mul) # 使用裝飾器插入的屬性和方法 return num4 if __name__ == '__main__': # 整體執(zhí)行流程: # 1. 打印 Operation 類名 # 2. 修改類的初始化參數(shù) # 3. 初始化類 # 4. 初始化完成后執(zhí)行一些方法 # 5. 給初始化的實例新增 mul 屬性和 plusNumber 方法 # 6. 實例執(zhí)行 add 函數(shù)并調(diào)用新增的裝飾函數(shù)和裝飾屬性 # 7. 輸出結(jié)果 op = Operation(3, 5) print(op.add()) # clsName: Operation # do something after the func... # 42
二、常用場景
1.記錄日志
# todo
2.性能測試
# todo
3.循環(huán)執(zhí)行
# todo
4.攔截器
# todo
5.數(shù)據(jù)預處理(數(shù)據(jù)清洗)
# todo
6.功能植入
# todo
到此這篇關(guān)于Python Decorator裝飾器的創(chuàng)建方法及常用場景的文章就介紹到這了,更多相關(guān)Python Decorator裝飾器內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python開發(fā)實例之python使用Websocket庫開發(fā)簡單聊天工具實例詳解(python+Websocket+J
這篇文章主要介紹了python開發(fā)實例之python使用Websocket庫開發(fā)簡單聊天工具實例詳解(python+Websocket+JS),需要的朋友可以參考下2020-03-03Python安裝第三方庫的方法(pip/conda、easy_install、setup.py)
這篇文章主要介紹了Python安裝第三方庫(pip/conda、easy_install、setup.py)的相關(guān)知識,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-05-05Python asyncore socket客戶端實現(xiàn)方法詳解
這篇文章主要介紹了Python asyncore socket客戶端實現(xiàn)方法,asyncore庫是python的一個標準庫,提供了以異步的方式寫入套接字服務的客戶端和服務器的基礎結(jié)構(gòu)2022-12-12巧妙使用Python裝飾器處理if...elif...else
大家好,今天在 Github 閱讀 EdgeDB[1] 的代碼,發(fā)現(xiàn)它在處理大量if…elif…else的時候,巧妙地使用了裝飾器,方法設計精巧,分享給大家一下,歡迎收藏學習,喜歡點贊支持2021-11-11Django Channels 實現(xiàn)點對點實時聊天和消息推送功能
這篇文章主要介紹了Django Channels 實現(xiàn)點對點實時聊天和消息推送功能,本文分步驟給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下2019-07-07