色婷婷狠狠18禁久久YY,CHINESE性内射高清国产,国产女人18毛片水真多1,国产AV在线观看

python中如何理解裝飾器代碼

林玟書2年前15瀏覽0評論

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

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

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

在簡單概括一下這兩個問題涉及到的Python 知識點 :

問題1:Python的函數對象,函數可以被賦值,函數可以作為參數傳遞,函數可以作為返回值。

問題2:Python 的 閉包

接下來,我們根據實例,逐一的介紹一下:

函數對象

Python一切皆對象,函數這一語法結構也是一個對象。函數被稱為第一類對象,函數可以被當做數據傳遞。在函數對象中,我們像使用一個普通對象一樣使用函數對象,比如更改函數對象的名字,或者將函數對象作為參數進行傳遞。

函數可以被賦值

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

函數可以作為參數傳遞

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

函數可以作為返回值

如上示例中,當函數(不帶括號)作為返回值時,返回的是函數的內存地址,代碼執行順序及結果,如下:

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

當 執行 return fun() 時,實際上是先調用fun_a函數,再將fun_a的返回結果作為fun_c的返回,運行代碼,結果如下:

閉包

定義:在計算機科學中,閉包(Closure)是詞法閉包(Lexical Closure)的簡稱,是引用了自由變量的函數。這個被引用的自由變量將和這個函數一同存在,即使已經離開了創造它的環境也不例外。所以,有另一種說法認為閉包是由函數和與其相關的引用環境組合而成的實體。閉包在運行時可以有多個實例,不同的引用環境和相同的函數組合可以產生不同的實例。

結合上面例子,一個閉包可以簡單理解為調用了一個函數fun_a,這個函數fun_a返回了一個函數fun_b。這個返回的函數fun_b就叫做閉包。在調用函數fun_a的時候傳遞的參數a、c就是自由變量。

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

修飾器

顧名思義,從字面意思可以理解為,它是用來"裝飾"Python的工具,使得代碼更具有Python簡潔的風格。裝飾器本質上是Python函數,能夠實現讓其他函數在不需要做任何代碼變動的前提下增加額外功能。

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

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

使用修飾器進行改造,如下:

執行fun_b相當于 fun_b = fun_a(fun_b) ,只是在定義fun_b時,在其前使用@fun_a 進行修飾。

再引入閉包進行改造,如下:

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

修飾器實現重試機制

簡單的重試機制實現

復雜的重試機制實現

支持重試次數和等待時間,如下:

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

https://www.toutiao.com/i6731320536732795405/