主頁 > 知識庫 > python中如何理解裝飾器代碼?

python中如何理解裝飾器代碼?

熱門標(biāo)簽:三亞電銷 梧州電銷 天津電銷 平?jīng)鲭婁N 黑龍江電銷 廊坊電銷 安順電銷 潛江電銷

先分解一下樓主提出的問題:

如何理解return一個(gè)函數(shù),它與return一個(gè)值得用法區(qū)別在哪?在wrapper函數(shù)中,為什么能返回一個(gè)在wrapper函數(shù)中沒有定義的func函數(shù)?

在簡單概括一下這兩個(gè)問題涉及到的Python 知識點(diǎn) :

接下來源碼,我們根據(jù)實(shí)例,逐一的介紹一下:

函數(shù)對象

Python一切皆對象,函數(shù)這一語法結(jié)構(gòu)也是一個(gè)對象。函數(shù)被稱為第一類對象,函數(shù)可以被當(dāng)做數(shù)據(jù)傳遞。在函數(shù)對象中,我們像使用一個(gè)普通對象一樣使用函數(shù)對象,比如更改函數(shù)對象的名字,或者將函數(shù)對象作為參數(shù)進(jìn)行傳遞。

函數(shù)可以被賦值

執(zhí)行上述代碼,輸出如下,請留意代碼中的注釋信息。

函數(shù)可以作為參數(shù)傳遞

執(zhí)行上述代碼,輸出如下源碼,請留意代碼中的注釋信息。

函數(shù)可以作為返回值

如上示例中,當(dāng)函數(shù)(不帶括號)作為返回值時(shí),返回的是函數(shù)的內(nèi)存地址,代碼執(zhí)行順序及結(jié)果,如下:

與上面代碼不同的是,接下來我們嘗試一下讓fun_b返回 return fun(),多了一個(gè)括號,代碼如下:

當(dāng) 執(zhí)行 return fun() 時(shí),實(shí)際上是先調(diào)用fun_a函數(shù),再將fun_a的返回結(jié)果作為fun_c的返回,運(yùn)行代碼,結(jié)果如下:

閉包

定義:在計(jì)算機(jī)科學(xué)中,閉包(Closure)是詞法閉包(Lexical Closure)的簡稱,是引用了自由變量的函數(shù)。這個(gè)被引用的自由變量將和這個(gè)函數(shù)一同存在,即使已經(jīng)離開了創(chuàng)造它的環(huán)境也不例外。所以,有另一種說法認(rèn)為閉包是由函數(shù)和與其相關(guān)的引用環(huán)境組合而成的實(shí)體。閉包在運(yùn)行時(shí)可以有多個(gè)實(shí)例,不同的引用環(huán)境和相同的函數(shù)組合可以產(chǎn)生不同的實(shí)例。

結(jié)合上面例子,一個(gè)閉包可以簡單理解為調(diào)用了一個(gè)函數(shù)fun_a,這個(gè)函數(shù)fun_a返回了一個(gè)函數(shù)fun_b。這個(gè)返回的函數(shù)fun_b就叫做閉包。在調(diào)用函數(shù)fun_a的時(shí)候傳遞的參數(shù)a、c就是自由變量。

上面例子中,函數(shù) fun_b 與環(huán)境變量 a,c 構(gòu)成閉包。在創(chuàng)建閉包的時(shí)候,我們通過fun_a 的參數(shù) a,c明確這兩個(gè)環(huán)境變量的取值,因此確定了函數(shù)的最終形式(y = 2b + 10)。我們只需要變換參數(shù)a,b就可以獲得不同的直線表達(dá)函數(shù)。由此,我們可以看到,閉包的引入提高代碼了代碼的可復(fù)用性,更加簡潔。執(zhí)行代碼,輸出結(jié)果如下:

修飾器

顧名思義,從字面意思可以理解為,它是用來"裝飾"Python的工具,使得代碼更具有Python簡潔的風(fēng)格。裝飾器本質(zhì)上是Python函數(shù),能夠?qū)崿F(xiàn)讓其他函數(shù)在不需要做任何代碼變動的前提下增加額外功能。

可以看出,fun_a(fun_b)的執(zhí)行過程如下:

執(zhí)行函數(shù)fun_a,將fun_b當(dāng)作參數(shù)傳進(jìn)去,fun_b()本身也是對象。執(zhí)行print (fun()) 代碼時(shí),先執(zhí)行了 fun_b(),然后打印'Run Function B' , 返回 2019-06-11 21:17:27 。print(fun()) 打印了fun_b()的返回結(jié)果 2019-06-11 21:17:27 。

使用修飾器進(jìn)行改造,如下:

執(zhí)行fun_b相當(dāng)于 fun_b = fun_a(fun_b) ,只是在定義fun_b時(shí),在其前使用@fun_a 進(jìn)行修飾。

再引入閉包進(jìn)行改造,如下:

在fun_a內(nèi)部的函數(shù)retry(),是如何獲取fun這個(gè)參數(shù)來執(zhí)行的?執(zhí)行fun_a函數(shù)return的是retry這個(gè)函數(shù),而retry并沒有接受fun這個(gè)傳參。這就是Python里的閉包的概念,閉包就是指運(yùn)行時(shí)自帶上下文(自由變量)的函數(shù),如這里的retry函數(shù),他運(yùn)行的時(shí)候自帶了上層函數(shù)fun_a傳給他的fun這個(gè)參數(shù),所以才可以在運(yùn)行時(shí)對fun進(jìn)行處理和輸出。

修飾器實(shí)現(xiàn)重試機(jī)制

簡單的重試機(jī)制實(shí)現(xiàn)

復(fù)雜的重試機(jī)制實(shí)現(xiàn)

支持重試次數(shù)和等待時(shí)間,如下:

進(jìn)一步深入了解修飾器,可以閱讀這篇文章:

標(biāo)簽:懷化 桂林 宜賓 洛陽 通化 連云港 廣安 巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《python中如何理解裝飾器代碼?》,本文關(guān)鍵詞  ;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。

  • 相關(guān)文章
  • 下面列出與本文章《python中如何理解裝飾器代碼?》相關(guān)的同類信息!
  • 本頁收集關(guān)于python中如何理解裝飾器代碼?的相關(guān)信息資訊供網(wǎng)民參考!
  • 收縮
    • 微信客服
    • 微信二維碼
    • 電話咨詢

    • 400-1100-266