五個(gè)Python裝飾器讓你的代碼量砍半

通過使用這些包裝器來提升您的Python游戲的效率和可讀性!
到目前為止,Python是我最喜歡的編程語言,因?yàn)樗Z法簡單,而且在機(jī)器學(xué)習(xí)和Web開發(fā)等多個(gè)領(lǐng)域都有強(qiáng)大的應(yīng)用。
盡管我已經(jīng)有五年多的編程經(jīng)驗(yàn),但除非絕對必要,裝飾器很少出現(xiàn)在我的視線中,比如使用@staticmethod?裝飾器來表示類中的靜態(tài)方法。
然而,在最近的一次合并請求審查中,我的同事為我的一個(gè)函數(shù)引入了一個(gè)定時(shí)器裝飾器,這改變了我的看法。這激發(fā)了我對裝飾器所能提供的大量其他功能的好奇心,提升了代碼的整潔度和可讀性。
因此,在這篇短文中,我們將探討Python封裝器的概念,并介紹可以改善我們Python開發(fā)過程的五個(gè)示例。

Python 封裝器
Python 封裝器是添加到另一個(gè)函數(shù)中的函數(shù),它可以在不直接改變源代碼的情況下添加額外的功能或修改其行為。它們通常以裝飾器的形式實(shí)現(xiàn),裝飾器是一種特殊的函數(shù),它將另一個(gè)函數(shù)作為輸入,并對其功能進(jìn)行一些修改。
封裝函數(shù)在各種情況下都很有用:
功能擴(kuò)展: 通過使用裝飾器封裝函數(shù),我們可以添加日志記錄、性能測量或緩存等功能。
代碼重用性: 我們可以將一個(gè)封裝函數(shù)甚至一個(gè)類應(yīng)用于多個(gè)實(shí)體,這樣可以避免代碼重復(fù),并確保不同組件的行為一致。
行為修改: 我們可以攔截輸入?yún)?shù),例如,驗(yàn)證輸入變量,而無需許多?assert?行。

示例:
讓我向您展示一些在日常工作中必須使用封裝器的示例:
1 - 計(jì)時(shí)器Timer
該封裝函數(shù)用于測量函數(shù)的執(zhí)行時(shí)間,并打印執(zhí)行時(shí)間。它對于剖析和優(yōu)化代碼非常有用。
為了在 Python 中創(chuàng)建裝飾器,我們需要定義一個(gè)叫做 timer 的函數(shù),它接受一個(gè)叫做 func 的參數(shù)來表示它是一個(gè)裝飾器函數(shù)。在 timer 函數(shù)中,我們定義另一個(gè)叫做 wrapper 的函數(shù),它接收通常傳遞給我們要裝飾的函數(shù)的參數(shù)。
在wrapper函數(shù)中,我們使用提供的參數(shù)調(diào)用所需的函數(shù)。我們可以這樣做:result = func(*args, **kwargs)。
最后,包裝函數(shù)返回裝飾函數(shù)的執(zhí)行結(jié)果。裝飾函數(shù)應(yīng)該返回對我們剛剛創(chuàng)建的包裝函數(shù)的引用。
要使用裝飾器,可以使用 @ 符號(hào)將其應(yīng)用到所需的函數(shù)。
輸出:
2- 調(diào)試器Debugger
通過打印每個(gè)函數(shù)的輸入和輸出,可以創(chuàng)建一個(gè)額外的有用的封裝函數(shù)來方便調(diào)試。通過這種方法,我們可以深入了解各種函數(shù)的執(zhí)行流程,而無需在應(yīng)用程序中使用多個(gè)打印語句。
我們可以使用 __name__ 參數(shù)獲取被調(diào)用函數(shù)的名稱,然后使用 args , kwargsparameters 打印傳遞給函數(shù)的內(nèi)容。
3 - 異常處理程序Exception Handler
異常處理程序 exception_handler 將捕獲 divide 函數(shù)中出現(xiàn)的任何異常,并進(jìn)行相應(yīng)的處理。
我們可以根據(jù)您的要求在封裝函數(shù)中自定義異常處理,例如記錄異?;驁?zhí)行額外的錯(cuò)誤處理步驟。
這對于簡化我們的代碼以及建立統(tǒng)一的異常處理和錯(cuò)誤記錄程序非常有用。
4 - 輸入驗(yàn)證器Input Validator
該封裝函數(shù)根據(jù)指定的條件或數(shù)據(jù)類型驗(yàn)證函數(shù)的輸入?yún)?shù)。它可以用來確保輸入數(shù)據(jù)的正確性和一致性。
另一種方法是在我們需要驗(yàn)證輸入數(shù)據(jù)的函數(shù)中創(chuàng)建無數(shù)的?assert?行。
為了在裝飾中添加驗(yàn)證,我們需要用另一個(gè)函數(shù)來封裝裝飾器函數(shù),該函數(shù)將一個(gè)或多個(gè)驗(yàn)證函數(shù)作為參數(shù)。這些驗(yàn)證函數(shù)負(fù)責(zé)檢查輸入值是否滿足某些標(biāo)準(zhǔn)或條件。
現(xiàn)在,validate_input 函數(shù)本身就充當(dāng)了裝飾器的角色。在封裝函數(shù)內(nèi)部,輸入和關(guān)鍵字參數(shù)將根據(jù)所提供的驗(yàn)證函數(shù)進(jìn)行檢查。如果任何參數(shù)未通過驗(yàn)證,則會(huì)引發(fā)一個(gè) ValueError,并給出一條提示無效參數(shù)的消息。
為了調(diào)用經(jīng)過驗(yàn)證的輸入,我們需要定義驗(yàn)證函數(shù)。例如,可以使用兩個(gè)驗(yàn)證函數(shù)。第一個(gè)函數(shù) lambda x: x > 0 檢查參數(shù)?x?是否大于0,第二個(gè)函數(shù) lambda y: isinstance(y, str) 檢查參數(shù) y 是否為字符串類型。
重要的是要確保驗(yàn)證函數(shù)的順序與它們要驗(yàn)證的參數(shù)的順序一致。
5 - 重試Retry
該封裝器會(huì)重試執(zhí)行指定次數(shù)的函數(shù),重試之間會(huì)有延遲。它在處理網(wǎng)絡(luò)或API調(diào)用時(shí)非常有用,這些調(diào)用偶爾會(huì)由于臨時(shí)問題而失敗。
為了實(shí)現(xiàn)這一點(diǎn),我們可以為我們的裝飾器定義另一個(gè)封裝函數(shù),與之前的示例類似。不過,這次我們可以傳遞特定的參數(shù),如 max_attemps 和 delay,而不是提供驗(yàn)證函數(shù)作為輸入變量。
當(dāng)被裝飾的函數(shù)被調(diào)用時(shí),wrapper 函數(shù)被調(diào)用。它將記錄嘗試的次數(shù)(從0開始),并進(jìn)入一個(gè)while循環(huán)。該循環(huán)嘗試執(zhí)行裝飾函數(shù),如果成功則立即返回結(jié)果。但是,如果出現(xiàn)異常,它將遞增嘗試計(jì)數(shù)器,并打印錯(cuò)誤消息,指出嘗試次數(shù)和出現(xiàn)的特定異常。然后使用 time.sleep 等待指定的延遲時(shí)間,然后再次嘗試執(zhí)行函數(shù)。
為了調(diào)用函數(shù),我們可以指定最大嘗試次數(shù)和每次調(diào)用函數(shù)之間的持續(xù)時(shí)間(以秒為單位)。
結(jié)論:
Python封裝器是強(qiáng)大的工具,可以提升您的Python編程體驗(yàn)。通過使用封裝器,你可以簡化復(fù)雜的任務(wù),提高代碼的可讀性,并提高工作效率。
在本文中,我們探討了五個(gè) Python 封裝器的示例:
Timer Wrapper
Debugger Wrapper
Exception Handler Wrapper
Input Validator Wrapper
Function Retry Wrapper
將這些封裝器集成到您的項(xiàng)目中,將幫助您編寫更簡潔、更高效的Python代碼,并使您的編程技能更上一層樓。

可以關(guān)注UP主熬夜整理的視頻:【2023版Python訓(xùn)練營】從入門到精通

本文翻譯自:
標(biāo)題:Five Python Decorators That Can Reduce Your Code By Half
地址:https://python.plainenglish.io/five-python-wrappers-that-can-reduce-your-code-by-half-af775feb1d5