1. 程式人生 > >Python中functiools.wraps()的功能以及用法詳解

Python中functiools.wraps()的功能以及用法詳解

        今天學習Pyhton學到了裝飾器,但是遇到視訊無法播放,附帶原始碼中有一個functools.wraps()的裝飾器,看了好久做了實驗才知道是幹什麼的。

        先看一下functool.wraps的定義以及闡述(由於我用的是虛擬機器,所以只能上圖片不能上程式碼了):


        大概意思是說,這個函式返回一個裝飾器,呼叫update_wrapper()函式,和裝飾器一起作為wraps()的剩餘的引數,預設引數是和update_wrapper()的相同,後面大概意思是這個是個簡單的函式去應用partial()和update_wrapper().(英語不好,只能翻譯出大概。見諒見諒。)

        在functools的原始檔程式碼中,有這樣的說明:


        大概意思是說:update_wrapper()和wraps()是幫助編寫可以處理naive內省的包裝器功能的工具。原諒我的英語不好,這裡的naive翻譯不出來,我只知道它的天真的意思。

        而wraps的引數是這樣定義的:


        表明,這個函式(functool.wraps)只會對這幾個屬性起作用,而這些屬性都是我們非常熟悉的,比如__doc__屬性,我們可以用來檢視幫助文件,從wraps的文件中,我猜測這個函式應該有partial()類似的功能。

        我們知道,python中partial()函式可以給某帶引數的函式的引數繫結一個預設值,呼叫的時候就無須傳遞引數了,那麼,這個函式(functool.wraps())是不是可以起到類似於繫結的作用,但是繫結的是原始檔的私有屬性。

        當裝飾器裝飾一個函式時,實際上就是將被裝飾的函式作為一個引數傳入裝飾器函式,返回一個閉包,而閉包內部呼叫這個函式,再另外多做一些事情。然後再由我們的函式名字去接收那個返回值的閉包的引用,達到了我們裝飾的目的,所以此時,我們的函式的__name__等屬性其實已經改變,變成了我們閉包的私有屬性。

        懷著試試看的態度,我寫了以下程式碼,得出瞭如下的結果:


        可見,這個函式確實是將被裝飾函式的__name__以及__doc__等屬性繫結到了原函式的上面。我把那個閉包的裝飾器

@functools.wraps(func)

        刪除掉,出現這樣的結果:


        所以,我得出這樣的總結:

        functools.wraps()這個函式,作為一個裝飾器去裝飾閉包,並且給這個裝飾器傳入一個引數,這個引數是閉包外的裝飾器裝飾的那個外部的被裝飾函式,此時,外部我們的自定義的函式的私有屬性如__name__、__doc__等還是為我們自定義的函式本身的私有屬性,而不會變成閉包的私有屬性。

謝謝大家看完,小白理解淺陋,還望各位指出問題所在。