tft每日頭條

 > 科技

 > python裝飾器參數化

python裝飾器參數化

科技 更新时间:2025-02-07 16:05:17

哈喽,各位小夥伴,衆所周知,如果要說你會python, 那麼裝飾器是必備技能,在python開發中,裝飾器的應用也非常廣泛。

不知小夥伴們在編程時有沒有這樣的苦惱:業務邏輯越複雜,函數處理邏輯也會複雜,從而函數中判斷邏輯也會增加,有時還不得不拆分幾個函數輔助完成,這會使得可閱讀性降低,代碼看上去很low,而且這樣做會使得函數通用性降低,程序中必然出現很多重複累贅的代碼。

上面的問題通過類似的裝飾器可以完美解決,而且隻用一個裝飾器名稱。閱讀以下内容你将明白類裝飾器原理,以及一個裝飾器實現:日志記錄、并發運行函數、添加互斥鎖、限制函數執行次數等實例,好了,讓我們進入今天的主題吧,(演示完整代碼在最後,開箱即用)

類裝飾器通用寫法

python裝飾器參數化(python類裝飾器裝飾器類)1

這是類裝飾器通用寫法

上圖代碼塊内容是類裝飾器最通用的寫法,裝飾器傳參與否,被裝飾函數傳參與否他否可以處理。

類裝飾器運行順序

python裝飾器參數化(python類裝飾器裝飾器類)2

類裝飾器運行順序

從上圖中的日志輸出我們不難看出類裝飾器運行順序為:①先實例化類裝飾器并執行__init__函數→②調用__call__方法→③調用call方法返回的main方法→④調用main方法返回的函數wapper→⑤運行被裝飾的方法

了解了執行順序,相信你對裝飾器類有一定了解,好了那我們直接看實例

實例1- 并發執行

可以并發執行被裝飾函數,這種做法在自動化中并發執行case,很有用

python裝飾器參數化(python類裝飾器裝飾器類)3

寫法

python裝飾器參數化(python類裝飾器裝飾器類)4

運行結果

從打印結果可以看出,打印書序是亂序,說明 并發執行了被裝飾函數,

實例2- 添加互斥鎖

用裝飾器給函數上鎖,簡單、高效、靈活性強,

python裝飾器參數化(python類裝飾器裝飾器類)5

寫法

python裝飾器參數化(python類裝飾器裝飾器類)6

運行結果

從打印結果可以看出,沒有并發執行,而是串行,按順序打印

實例3- 記錄日志

python裝飾器參數化(python類裝飾器裝飾器類)7

寫法

python裝飾器參數化(python類裝飾器裝飾器類)8

運行結果

從test_log文件裡,可以看出,相應信息被記錄在txt文件中

看了類裝飾器通用寫法,以及相關實例後,依葫蘆畫瓢,整體結構複制後,添加函數,就可以封裝屬于自己的類裝飾器,讓一個裝飾器完成多個功能,相信這對你程序有幫助。

有看不懂的地方,或者需要我幫你封裝的,歡迎留言咨詢,有問必答,相互學習,共赢~~~

示例源碼:

import functools import copy from concurrent.futures import ThreadPoolExecutor as TPool from threading import Lock import time import functools class LeiWrapper: #定義裝飾器類 def __init__(self,*args,**kwargs): #定義類裝飾器初始化方法,用于接收類裝飾器傳入的參數 self.args = args self.kwargs = kwargs def main(self): #函數包裝功能 預處理 print("這是類裝飾器中的第一個功能函數") @functools.wraps(self.func) # 保持函數本身信息不變,比如函數name、注釋信息等 def wapper(*args,**kwargs): # 定義包裹函數,用于接收函數調用時傳入參數 print("4444") data = self.func(*args,**kwargs) # 調用運行被裝飾的函數 return data # 返回函數處理完的數據 return wapper def RunBF(self): @functools.wraps(self.func) def mm(*arg,**kwarg): #接收函數調用傳入參數 data = ["1","2","3"] #用于并發的數據 with TPool(4) as ex: #啟動有2個線程的線程池 start = time.time() for i in data: kwarg[i] = "參數 " str(i) #改變參數 ex.submit(self.func,*arg,**kwarg) #并發執行函數 end = time.time() print(end - start) return mm def LockFun(self): @functools.wraps(self.func) def mm(*arg,**kwarg): #接收函數調用傳入參數 with Lock(): funResult = self.func(*arg,**kwarg) #給函數加鎖 return funResult #返回被裝飾函數的返回值 return mm def logs(self): @functools.wraps(self.func) def mm(*arg,**kwarg): #接收函數調用傳入參數 with open("test_log.txt","a ",encoding="UTF-8") as writer: funResult = self.func(*arg,**kwarg) message = "函數被執行了,傳入參數為: " str(arg) ",關鍵字參數為:" str(kwarg) message = message "函數執行結果為: " funResult "\n" writer.write(message) return funResult #返回被裝飾函數的返回值 return mm def __call__(self,func): self.func = func if self.kwargs.get("menthod") == "BF": #根據參數判斷裝飾器工作内容 return self.RunBF() if self.kwargs.get("menthod") == "Lock": #根據參數判斷裝飾器工作内容 return self.LockFun() if self.kwargs.get("menthod") == "logs": #根據參數判斷裝飾器工作内容 return self.logs() return self.main() @LeiWrapper(menthod="logs") def test(*arg,**kwarg): time.sleep(2) print("函數被執行了,傳入參數為: " str(arg) ",關鍵字參數為:" str(kwarg)) return "執行完成" test("參數1",key="wwwwwww") test("參數2",key="eeeeeee") test("參數3",key="rrrrrr") test("參數4",key="tttt")

,

更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!

查看全部

相关科技资讯推荐

热门科技资讯推荐

网友关注

Copyright 2023-2025 - www.tftnews.com All Rights Reserved