Python?Decorator裝飾器的創(chuàng)建方法及常用場景分析
前言
1.裝飾器本質(zhì)是一個語法糖,是對被裝飾方法或類進(jìn)行的功能擴(kuò)充,是一種面向切面的實(shí)現(xiàn)方法
2.裝飾器可以分成方法裝飾器和類裝飾器,他們的區(qū)別是一個是用函數(shù)實(shí)現(xiàn)的裝飾器,一個是用類實(shí)現(xiàn)的裝飾器,他們也都能在方法和類上進(jìn)行裝飾
3.類裝飾器看起來結(jié)構(gòu)更加清晰,因此下面的代碼實(shí)現(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)榈谝粋€入?yún)⒌闹凳菍?shí)例本身self
# 修改被裝飾方法的入?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...")
# -------------------------------------
# 給類實(shí)例增加增加屬性和方法 ---------------------
cls.mul = 3 # 增加屬性
cls.plusNumber = self.plusNumber # 增加方法
# -------------------------------------------
# 返回實(shí)例
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. 給初始化的實(shí)例新增 mul 屬性和 plusNumber 方法
# 6. 實(shí)例執(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ù)預(yù)處理(數(shù)據(jù)清洗)
# todo
6.功能植入
# todo
到此這篇關(guān)于Python Decorator裝飾器的創(chuàng)建方法及常用場景的文章就介紹到這了,更多相關(guān)Python Decorator裝飾器內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python內(nèi)置函數(shù)map()的具體使用
Python中的map()函數(shù)是一個高效的內(nèi)置函數(shù),用于將指定函數(shù)應(yīng)用于序列的每個元素,通過接收一個函數(shù)和一個或多個序列,本文就來詳細(xì)的介紹一下如何使用,感興趣的可以了解一下2024-09-09
利用Python中的pandas庫對cdn日志進(jìn)行分析詳解
這篇文章主要介紹了利用Python中的pandas庫進(jìn)行cdn日志分析的相關(guān)資料,文中分享了pandas對cdn日志分析的完整示例代碼,然后詳細(xì)介紹了關(guān)于pandas庫的相關(guān)內(nèi)容,需要的朋友可以參考借鑒,下面來一起看看吧。2017-03-03
pytorch中的hook機(jī)制register_forward_hook
這篇文章主要介紹了pytorch中的hook機(jī)制register_forward_hook,手動在forward之前注冊hook,hook在forward執(zhí)行以后被自動執(zhí)行,下面詳細(xì)的內(nèi)容介紹,需要的小伙伴可以參考一下2022-03-03
使用Python實(shí)現(xiàn)圖片和base64轉(zhuǎn)換工具
這篇文章主要為大家詳細(xì)介紹了如何使用Python中的base64模塊編寫一個工具,可以實(shí)現(xiàn)圖片和Base64編碼之間的轉(zhuǎn)換,感興趣的小伙伴可以了解下2025-02-02
Python中多進(jìn)程處理的Process和Pool的用法詳解
在Python編程中,多進(jìn)程是一種強(qiáng)大的并行處理技術(shù),Python提供了兩種主要的多進(jìn)程處理方式:Process和Pool,本文將詳細(xì)介紹這兩種方式的使用,希望對大家有所幫助2024-02-02
Python實(shí)現(xiàn)去除列表中重復(fù)元素的方法小結(jié)【4種方法】
這篇文章主要介紹了Python實(shí)現(xiàn)去除列表中重復(fù)元素的方法,結(jié)合實(shí)例形式總結(jié)分析了Python列表去重的4種實(shí)現(xiàn)方法,涉及Python針對列表的遍歷、判斷、排序等相關(guān)操作技巧,需要的朋友可以參考下2018-04-04
Python3 Post登錄并且保存cookie登錄其他頁面的方法
今天小編就為大家分享一篇Python3 Post登錄并且保存cookie登錄其他頁面的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-12-12

