[Python] 裝飾器(一)

1. 裝飾器是什么?
裝飾器(Decorator )作為python語(yǔ)言面試的必免考點(diǎn)!如果沒(méi)有回答上來(lái),在面試官心中你的技術(shù)就大打折扣!
首先從字面上去理解,裝飾就是修飾,點(diǎn)綴的意思。相當(dāng)于是函數(shù)功能的擴(kuò)展。
裝飾器本質(zhì)上也是Python的函數(shù),其他函數(shù)在不需要做任何代碼變動(dòng)的前提下增加額外功能,裝飾器的返回值也是一個(gè)函數(shù)對(duì)象。
2. 裝飾器應(yīng)用場(chǎng)景
切面需求的場(chǎng)景,
比如:插入日志、性能測(cè)試、事務(wù)處理、緩存、權(quán)限校驗(yàn)等場(chǎng)景。
有了裝飾器,就可以抽離出大量與函數(shù)功能本身無(wú)關(guān)的雷同代碼并繼續(xù)重用。
進(jìn)一步說(shuō):裝飾器的作用就是為已經(jīng)存在的對(duì)象添加額外的功能。
3. 裝飾器背景
首先看一個(gè)函數(shù)

def driving():
      print("i'm driving")

現(xiàn)在有一個(gè)新的需求,希望可以記錄下函數(shù)的執(zhí)行日志,于是在代碼中添加日志代碼:

def driving():
      print("i'm driving")
      logging.info("driving is running")

假設(shè)stoping , parking 都有類似的需求。難道也把每個(gè)logging函數(shù)寫道函數(shù)內(nèi)部?這樣就會(huì)造成大量的冗余代碼。如何必免這樣的情況產(chǎn)生?
重新定義一個(gè)函數(shù):專門處理日志 ,日志處理完之后再執(zhí)行真正的業(yè)務(wù)代碼。

def  record_logging(func):
       logging.info("%s is running" % func.__name__)
       func()

def driving():
      print("i'm driving")

record_logging(driving):

邏輯上很清晰, 但是如果這樣做,每次都要將一個(gè)函數(shù)作為參數(shù)傳遞給record_logging函數(shù)。并且這樣做破壞原來(lái)的函數(shù)結(jié)構(gòu)。之前運(yùn)行的driving 函數(shù),現(xiàn)在需要運(yùn)行 record_logging函數(shù)。
如何在不破壞原來(lái)的函數(shù)基礎(chǔ),實(shí)現(xiàn)這樣的功能? 答案就是裝飾器的使用。

4. 裝飾器使用

def  record_logging(func):
         def wrapper(*args, **kwargs):
              logging.info("%s is running" % func.__name__)
              return func(*args, **kwargs)
        return wrapper

def driving():
      print("i'm driving")

driving = record_logging(driving)
driving ()

函數(shù)record_logging 就是裝飾器,真正執(zhí)行的業(yè)務(wù)函數(shù)driving 被包含在里面了,看上去 driving 被函數(shù)record_logging 裝飾了。
@符號(hào)是裝飾器的語(yǔ)法糖,在定義函數(shù)的時(shí)候使用,避免再一次賦值操。

def  record_logging(func):
         def wrapper(*args, **kwargs):
              logging.info("%s is running" % func.__name__)
              return func(*args, **kwargs)
        return wrapper

@record_logging
def driving():
      print("i'm driving")

@record_logging
def stoping():
      print("i'm stoping")


driving()
stoping()

加入@ 語(yǔ)法糖之后,就能省略driving = record_logging(driving)
這一步驟。如果有其它類似的函數(shù)調(diào)用就可以直接用裝飾器。提高了程序的可重復(fù)利用性,并增加了程序的可讀性。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容