python裝飾器詳解

python之裝飾器詳解

一、裝飾器定義

定義一個函數,可以接受一個函數作為參數,對該函數進行一些包裝,不改變函數的本身。

二、裝飾器四部曲(分解)

1、函數可賦值給變量。若賦值給變量的是調用后的函數,變量的值就是return的返回值。

切記:函數賦值給變量,只看return的值。分清楚函數是處于調用狀態還是未被調用狀態。若函數沒有寫return,默認return為None。

例如:

python裝飾器詳解

解釋:把函數foo賦值給a和b,a賦值的是調用后的函數,變量的值就是返回值。b賦值的是調用前的函數,所以b就是那個賦值的函數。函數本身+(),就是調用。

可以用callable判斷某個東西是否可以被調用,call是調用的意思,able是“能的”形容詞后綴,翻譯就是可調用的。b是函數本身,可以被調用,a是函數的結果,不能被調用。

小技巧:

我們可以用.name看一個函數的信息,例如:b函數其實就是‘foo’函數。

python裝飾器詳解

2、函數可以作為參數傳遞,在函數內部仍可進行調用??梢詫⒑瘮翟趦炔慷x理解為一個變量在內部定義。

python裝飾器詳解

解釋:我先定義一個函數foo,然后再定義一個函數bar,我調用foo的時候,即foo(),沒有設置傳遞參數,打印了1234.我調用bar的時候,傳遞了一個函數foo作為參數,即bar(foo),得到的結果就是func(),調用函數本身,所以得到1234的結果。

3、函數可嵌套定義,并可在內部直接調用。且可調用外層函數傳遞的參數。這一步很關鍵。

python裝飾器詳解

解釋:內層函數可以調用外層函數傳遞的參數,f(1234)傳遞給了內層函數。內層沒有找到x變量的值,就要去臨近的外層變量尋找。外層傳遞一個1234,就傳遞給內層了。最后一行的bar()是在外層函數的內部直接調用內層函數。

函數嵌套定義就是可以把函數看成定義一個變量,類似于b=1,還有就是內層函數可以調用外層函數傳遞的參數,記住這兩點就可以了。

4、函數可以作為return的返回值

python裝飾器詳解

解釋:上面定義了一個函數,下面定義了一個函數返回函數。對變量a進行賦值,可以使用a.__name__看到a的函數名,a就是bar,為什么是bar呢,因為第一條:給變量a賦值的時候,只看return,return的是函數的函數func,所以是bar。

三、組合起來就是裝飾器

python裝飾器詳解

解釋:最后的foo就是wrapper,就是deco(foo),是內層函數“g()”,可以用foo.name查看,就是wrapper,callable(foo),可以看到它可以調用。

還有一點,如下圖,筆者在學習過程中碰到的一點疑問:

python裝飾器詳解

上面的三個過程,第一個是給變量賦值的過程,第二個是打印變量的過程,第三個是函數調用的過程。變量賦值看return,不要看他出現什么結果,這個時候就是把return的1賦值給a,所以打印a才會出來1,函數調用的過程,就是執行函數內部程序的過程,函數內部有一個打印,一個return,所以才會出現這樣的結果。

這樣,我們就很好理解上面的結果了。

python裝飾器詳解

上面的這個“函數賦值給變量”就是裝飾器的核心原理,裝飾器接受函數作為參數完成調用,再將返回結果賦值給該函數同名的變量。以后再通過該變量名調用,就是被裝飾器裝飾過的函數。

四、python裝飾器用法:@

python裝飾器詳解

解釋:@deco相當于foo=deco(foo)。

1、內層函數也可以定義參數:

python裝飾器詳解

解釋:參數的傳遞是先傳給wrapper,wrapper在把這個參數傳遞給func進行調用。wrapper接受的參數的個數要跟foo的一樣,我要通過wrapper轉給foo。

2、裝飾器方法總結:

通常最內層函數的倒數第二層函數,定義接受一個函數參數

裝飾器內部嵌套定義了什么函數,就要講該函數作為return返回值,未調用的。

最內層函數的參數定義最好和傳人的參數定義一致,或者使用(*arg,*kwargs)這種可變參數的定義方式。

python裝飾器詳解

裝飾器外層函數只會執行一次。外層的操作執行完成后,就不會再輸出了。執行的都是內層函數wrapper。

python裝飾器詳解

對裝飾的函數進行屬性傳遞:被裝飾的函數的name,名稱,doc注釋等等,都無法保留,都是內層函數的,這個時候就要把wrapper的屬性改掉,改成我們接受函數的屬性。也有一個專門的模塊:from functools import wraps。用法@wraps(func)

python裝飾器詳解

python裝飾器詳解

nonlocal:python可以使用外部函數變量,無法修改外部函數自身。此時可以用nonlocal關鍵字標記需要修改的變量就可以修改該變量的值了。例如統計函數的次數:

python裝飾器詳解

帶參數的裝飾器:無非就是再加一層,內部可以不用動。如下,增加一個參數123.

python裝飾器詳解

原創文章,作者:N24_yezi,如若轉載,請注明出處:http://www.www58058.com/67878

(11)
N24_yeziN24_yezi
上一篇 2017-02-08
下一篇 2017-02-08

相關推薦

  • n28 第二周作業

    n28 第二周作業

    Linux干貨 2017-12-09
  • DHCP服務介紹及搭建

    DHCP服務介紹及搭建

    2018-01-16
  • 相識–Varnish

    Varnish與一般服務器軟件類似,分為master(management)進程和child(worker,主要做cache的工作)進程。master進程讀入命令,進行一些初始化,然后fork并監控child進程。child進程分配若干線程進行工作,主要包括一些管理線程和很多woker線程。 VCL:?”域“專有類型的配置語言 VCL有多個狀態引擎,狀態之間…

    Linux干貨 2017-11-13
  • linux基礎知識:文件管理,bash特性

    本文簡要介紹了文件類的管理命令,包括mv、cp、mkdir等等。還介紹了一些萬用字符的用法。

    2017-12-12
  • 文件壓縮和軟件包管理

    Linux壓縮打包 壓縮是一種通過特定的算法來減小計算機文件大小的機制。有利于文件在網絡上的傳輸,節約帶寬。在Linux中,壓縮是以后綴名區分文件的。(Linux中很少見)壓縮文件都會呈現醒目的紅色。 注意!以下壓縮軟件只能壓縮文件而不能壓縮目錄。不能對目錄直接壓縮! compress命令 compress這個命令是非常老舊的一款命令,現在基本已經不用了 而…

    Linux干貨 2016-08-24
  • 第十周-Centos啟動流程及Shell腳本編程

    一、CentOS啟動流程 POST –> Boot Sequence(BIOS) –> Boot Loader (MBR) –> Kernel(ramdisk) –> rootfs –> switchroot –> /sbin/init –…

    2017-10-14

評論列表(1條)

  • luoweiro
    luoweiro 2017-02-23 07:40

    原理分解的很詳細,步驟完善。

欧美性久久久久