您好,登錄后才能下訂單哦!
本篇文章為大家展示了python中如何使用裝飾器,內(nèi)容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細介紹希望你能有所收獲。
大家都知道了裝飾器是用來拓展函數(shù)功能的,但是別忘了裝飾器本身也是函數(shù),當然也可以通過給裝飾器增加參數(shù)來拓展功能。
我們繼續(xù)昨天的案例講解帶參數(shù)裝飾器:現(xiàn)在客戶又提需求了,客戶發(fā)現(xiàn)周一到周五收銀機的帳目很清楚,但是周六日賬目有點混亂??蛻粝M浙y機把周六和周日的所有交易記錄保存到日志文件中,周一到周五的交易記錄不需要保存。
分析客戶需求,按照我們昨天學習的裝飾器的內(nèi)容,可以很快想到解決方案,再寫一個裝飾器用來保存交易記錄。但是這里有一個難點,客戶要求周一至周五的不保存,周六周日的保存,怎么辦呢?
在這里就需要用到帶參數(shù)裝飾器了,具體代碼如下:
import functools from datetime import datetime # 這行代碼是獲取當前是星期幾,周一對應對應1,周六對應6,周日對應7 # day_week = datetime.now().isoweekday() # 今天是周二,明天周三,不會觸發(fā)記錄日志的條件,暫注釋,方便測試 day_week = 7 # 為了測試,假定今日是周日。實際使用時注釋這行,取消注釋上面一行。 def check_week(chk): def inner(func): @functools.wraps(func) def inner_chk(*args, **kwargs): if chk: with open('log.txt', mode='a', encoding='utf8') as f: f.write(f'交易記錄:折扣值是{args[0]},商品單價{args[1]},商品數(shù)量{args[2]},交易時間是{datetime.now()}\n') return func(*args, **kwargs) return inner_chk return inner def checkdisct(func): @functools.wraps(func) def inner(*args, **kwargs): disct = args[0] if disct >= 0.5 and disct <= 1: print('折扣值合理!') return func(*args, **kwargs) else: print('折扣值不合理!') return inner def checkpwd(func): @functools.wraps(func) def inner(*args, **kwargs): pwd = input('請輸入密碼:') if pwd == "123456": print("密碼正確!") return func(*args, **kwargs) else: print('密碼錯誤!') return inner # 判斷不是星期六和日則設置day_week為0,不觸發(fā)記錄log;若是周六、周日會觸發(fā)記錄log。 if day_week != 6 or day_week != 7: day_week = 0 @checkpwd @checkdisct @check_week(day_week) def count(x, prince, number): '''功能:計算商品應付款和實付款的函數(shù)。 參數(shù):x是float型,指定折扣額度;prince是float型,指定商品的單價;number是int型,指定商品的數(shù)量。''' result = prince * number pay = result * x print(f'總價是{result}元,實付{pay}元') count(0.8, 2.88, 100) count(0.3, 2.88, 100) out: 請輸入密碼:123456 密碼正確! 折扣值合理! 總價是288.0元,實付230.4元 請輸入密碼:1 密碼錯誤!
測試結(jié)果完全滿足客戶的需求,實現(xiàn)了周一至五不記錄交易log,周六日記錄交易log。
直接讀上面大段代碼對于裝飾器運用不熟練的朋友可能會有些懵懂,下面詳細講解帶參數(shù)裝飾器。
帶參數(shù)裝飾器至少有3層結(jié)構,即最少包含3層def和3層return。
第一層:負責接收裝飾器自身的參數(shù),再返回第二層函數(shù)。
第二層:負責接收被裝飾的函數(shù),再返回第三層函數(shù)。
第三層:這一層做的事情很多,按功能劃分為3塊。
負責接收被裝飾函數(shù)的參數(shù)。
對裝飾器自身的參數(shù)進行解析處理,若其滿足某條件則做某動作,不滿足條件則不做動作(或做別的動作)。
返回被裝飾的函數(shù)及其參數(shù)。
def check_week(chk): # 帶參數(shù)裝飾器,chk是判斷條件,chk不是0則記錄交易日志,chk是0則不記錄 def inner(func): # func是被裝飾的函數(shù)名 @functools.wraps(func) def inner_chk(*args, **kwargs): # *args和**kwargs是被裝飾的函數(shù)參數(shù) if chk: #判斷條件是否滿足,若不為0則將交易記錄和交易時間保存到log.txt文件 with open('log.txt', mode='a', encoding='utf8') as f: f.write(f'交易記錄:折扣值是{args[0]},商品單價{args[1]},商品數(shù)量{args[2]},交易時間是{datetime.now()}\n') return func(*args, **kwargs) # 返回被裝飾的函數(shù)及其參數(shù) return inner_chk # 返回第三層函數(shù)inner_chk return inner # 返回第二層函數(shù)inner
以上案例詳細講解了帶參數(shù)裝飾器的構造,要學習裝飾器必須多加練習才能真正掌握。
關于帶參數(shù)裝飾器的運用場景有很多,比較常見的有是否記錄業(yè)務日志,是否生成性能日志,使用測試數(shù)據(jù)庫運行或使用生產(chǎn)數(shù)據(jù)庫運行等等,具體要因業(yè)務需求而定。
關于裝飾器的運用,除了可以自己寫的裝飾器用,也有一些官方或第三方提供的裝飾器非常好用。例如之前有提及的@functools.wraps裝飾器。
這里再補充一個numba的jit裝飾器,功能是通過即時編譯的方法提升python函數(shù)運行效率。在涉及大量循環(huán)運算的場合建議嘗試一下。以下是測試代碼。
from numba import jit import time @jit def fib(n): if n <= 2: return 1 else: return fib(n - 1) + fib(n - 2) start = time.time() print(fib(40)) end = time.time() print(f"用時:{end - start}秒") out: 102334155 用時:1.001574993133545秒
大家猜猜如果注釋掉@jit,運行時間時間需要多少秒?
上述內(nèi)容就是python中如何使用裝飾器,你們學到知識或技能了嗎?如果還想學到更多技能或者豐富自己的知識儲備,歡迎關注億速云行業(yè)資訊頻道。
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。