搜尋
首頁後端開發Python教學Python中的裝飾器是什麼及怎麼使用

使用環境為: Python 3.6.8

Python中的裝飾器是什麼及怎麼使用

#什麼是裝飾器

#要瞭解裝飾器之前,我們需要了解什麼是閉包函數。

閉包函數

我們簡單寫個demo,再解釋一下什麼是閉包函數。

def exterFunc(x):
  def innerFunc(y):
    return x * y
  
  return innerFunc

def main() -> None:
  f = exterFunc(6)
  result = f(5)

  print(result)

if __name__ == '__main__':
  main()

可以看到,上述程式碼所示,所謂的閉包函數是指: 閉包函數是指在函數中再定義函數,內部函數可以存取外部的變量,在外部函數中,將內部函數作為返回值返回。

可以看到上述例子中,我們定義了exterFunc的函數,它將接收一個形參x,在exterFunc函數中又中定義了innerFunc,它也接收一個形參y, 在innerFunc函數中,傳回x * y,沒錯,內部函數可以存取外部函數傳入的變量,最後將exterFunc作為返回值返回,這就是閉包函數。

最簡單的裝飾器

裝飾器是一種很特殊的函數,可以接收函數作為形參,且傳回一個新的函數,在我們上一篇介紹生成器的時候,還記得我們使用memory_profiler函式庫來列印函數的記憶體運行情況麼?這就是用的裝飾器。

Python中的裝飾器是什麼及怎麼使用

我們可以寫個最簡單的例子,來闡述一下python裝飾器,即:

def foo(func):
    def wrapper():
        print("装饰器开始运行了")
        func()
        print("装饰器结束运行了")

    return wrapper

@foo
def sayHello():
    print("hello pdudo in juejin")

def main() -> None:
  sayHello()

if __name__ == '__main__':
  main()

上面程式碼,我們定義了一個裝飾器foofoo需要傳入一個函數,foo內部有一個函數wrapper。這樣的函數中包函數,我們稱之為閉包函數,後面會介紹閉包函數。言歸正傳,在wrapper函數中,我們可以在執行func函數的時候,再執行前後語句。

需要呼叫裝飾器的時候,只需要@加上函數名稱即可。

為什麼需要裝飾器

要解釋這個問題,我們可以看來了解下,裝飾器解決了一些什麼問題:

  • 解決程式碼重複性,對於經常需要實現類似的功能而言,可以將該功能抽離出來,作為裝飾器來調用,從而避免程式碼重複。

  • 增強程式碼可讀性,在不修改原始程式碼的前提下,可以利用裝飾器在函數前後增加程式碼,例如處理異常、記錄日誌等等,可以利用裝飾器將附加功能和函數主要功能分開,增加程式碼可讀性。

說了這麼多,我們來列舉一個最簡單的例子,利用裝飾器列印一下函數的運行時間。

import time

def getExecTimers(func):
  def wrapper():
    startTimes = time.time()
    func()
    endTimes = time.time()
    print("函数运行时间: " , endTimes - startTimes ,"s")
  return wrapper

@getExecTimers
def testFunc():
  print("开始执行函数")
  time.sleep(5)
  print("函数执行结束")

def main() -> None:
  testFunc()
  
if __name__ == '__main__':
  main()

這個裝飾器,會記錄函數的運行時間。可以看到,我們為這個函數增加了一個附屬功能,但是又沒有修改到原始函數。

上述案例,應該可以證明為什麼需要使用裝飾器了。

裝飾器用法

上述我們討論了最簡單的裝飾器寫法,並且寫了一個小功能,即列印函數的運行時間。接下來,我們要看下裝飾器的其他寫法。

不是用語法糖呼叫

還記得上面我們呼叫裝飾器,是使用的@ 裝飾器名稱麼?其實這是python的語法糖,如果不是用語法糖的話,應該是這樣來使用的:

def foo(func):
    def wrapper():
        print("装饰器开始运行了")
        func()
        print("装饰器结束运行了")

    return wrapper


def sayHello():
    print("hello pdudo in juejin")

def main() -> None:
  f1 = sayHello
  f2 = foo(f1)

  f2()

if __name__ == '__main__':
  main()

完整的寫法應該如下程式碼所示,這是一個完整的閉包調用邏輯。

f1 = sayHello
f2 = foo(f1)

f2()

而在函數前加上@ 裝飾器名稱, 是一種python的語法糖

帶參數的裝飾器

這裡要做一個鋪墊,在python中,有2個特殊的變量,分別為*args**kwargs,都是用來處理不定量參數的,分別代表的意義為:

  • *args: 將會將參數打包為元組

  • **kwargs: 將會打包字典傳遞給函數

def foo(func):
    def wrapper(*args,**kwargs):
        print("装饰器开始运行了")
        print("装饰器捕获到的参数: " ,args,**kwargs)
        func(*args,**kwargs)
        print("装饰器结束运行了")

    return wrapper

@foo
def sayHello(a,b,c,dicts):
    print("传入的参数: " , a,b,c)
    print("传入的参数: " , dicts)

def main() -> None:
  sayHello(1,2,3,{"name":"juejin"})

if __name__ == '__main__':
  main()

在裝飾器中,若我們要給函數傳遞參數,是需要先將參數傳遞給裝飾器,而在裝飾器中接收後再進行傳遞的,所以程式碼才會是這樣的:

def foo(func):
    def wrapper(*args,**kwargs):
        print("装饰器开始运行了")
        print("装饰器捕获到的参数: " ,args,**kwargs)
        func(*args,**kwargs)
        print("装饰器结束运行了")

首先,我們在做傳遞呼叫的時候,wrapper應該呼叫形參來接收,接收後,再進行傳遞給函數func

以上是Python中的裝飾器是什麼及怎麼使用的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文轉載於:亿速云。如有侵權,請聯絡admin@php.cn刪除
您如何切成python列表?您如何切成python列表?May 02, 2025 am 12:14 AM

SlicingaPythonlistisdoneusingthesyntaxlist[start:stop:step].Here'showitworks:1)Startistheindexofthefirstelementtoinclude.2)Stopistheindexofthefirstelementtoexclude.3)Stepistheincrementbetweenelements.It'susefulforextractingportionsoflistsandcanuseneg

在Numpy陣列上可以執行哪些常見操作?在Numpy陣列上可以執行哪些常見操作?May 02, 2025 am 12:09 AM

numpyallowsforvariousoperationsonArrays:1)basicarithmeticlikeaddition,減法,乘法和division; 2)evationAperationssuchasmatrixmultiplication; 3)element-wiseOperations wiseOperationswithOutexpliitloops; 4)

Python的數據分析中如何使用陣列?Python的數據分析中如何使用陣列?May 02, 2025 am 12:09 AM

Arresinpython,尤其是Throughnumpyandpandas,weessentialFordataAnalysis,offeringSpeedAndeffied.1)NumpyArseNable efflaysenable efficefliceHandlingAtaSetSetSetSetSetSetSetSetSetSetSetsetSetSetSetSetsopplexoperationslikemovingaverages.2)

列表的內存足跡與python數組的內存足跡相比如何?列表的內存足跡與python數組的內存足跡相比如何?May 02, 2025 am 12:08 AM

列表sandnumpyArraysInpythonHavedIfferentMemoryfootprints:listSaremoreFlexibleButlessMemory-效率,而alenumpyArraySareSareOptimizedFornumericalData.1)listsStorReereReereReereReereFerenceStoObjects,with withOverHeadeBheadaroundAroundaround64byty64-bitsysysysysysysysysyssyssyssyssysssyssys2)

部署可執行的Python腳本時,如何處理特定環境的配置?部署可執行的Python腳本時,如何處理特定環境的配置?May 02, 2025 am 12:07 AM

toensurepythonscriptsbehavecorrectlyacrycrosdevelvermations,分期和生產,USETHESTERTATE:1)Environment varriablesForsimplesettings,2)configurationfilesfilesForcomPlexSetups,3)dynamiCofforComplexSetups,dynamiqualloadingForaptaptibality.eachmethodoffersuniquebeneiquebeneqeniquebenefitsandrefitsandrequiresandrequiresandrequiresca

您如何切成python陣列?您如何切成python陣列?May 01, 2025 am 12:18 AM

Python列表切片的基本語法是list[start:stop:step]。 1.start是包含的第一個元素索引,2.stop是排除的第一個元素索引,3.step決定元素之間的步長。切片不僅用於提取數據,還可以修改和反轉列表。

在什麼情況下,列表的表現比數組表現更好?在什麼情況下,列表的表現比數組表現更好?May 01, 2025 am 12:06 AM

ListSoutPerformarRaysin:1)DynamicsizicsizingandFrequentInsertions/刪除,2)儲存的二聚體和3)MemoryFeliceFiceForceforseforsparsedata,butmayhaveslightperformancecostsinclentoperations。

如何將Python數組轉換為Python列表?如何將Python數組轉換為Python列表?May 01, 2025 am 12:05 AM

toConvertapythonarraytoalist,usEthelist()constructororageneratorexpression.1)intimpthearraymoduleandcreateanArray.2)USELIST(ARR)或[XFORXINARR] to ConconverTittoalist,請考慮performorefformanceandmemoryfformanceandmemoryfformienceforlargedAtasetset。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

mPDF

mPDF

mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

將Eclipse與SAP NetWeaver應用伺服器整合。

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)