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、函數可以作為參數傳遞,在函數內部仍可進行調用。可以將函數在內部定義理解為一個變量在內部定義。

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 16:15
下一篇 2017-02-08 20:06

相關推薦

  • 26期全程班-第一周博客作業

    1、描述計算機的組成與功能。 計算機由以下五大單元組成: 一:CPU的算法計算和邏輯判斷單元; 二:CPU的控制單元;協調各設備協同工作。 三:內存:RAM(random accace memory)隨機讀取內存;數據處理的必經路段。 四:輸入設備:鍵盤、鼠標等;負責數據的輸入。 五:輸出設備:屏幕、終端、文件、硬盤等;負責數據的輸出 2、按系列羅列Linu…

    Linux干貨 2016-12-30
  • dd工具

    dd     dd命令:convert and copy a file     用法:        ddif=/PATH/FROM/SRC of=/PATH/TO/DEST       &…

    Linux干貨 2016-09-02
  • mariadb基礎應用

    mariadb基礎應用 一、 前言 MariaDB is one of the most popular database servers in the world. It’s made by the original developers of MySQL and guaranteed to stay open source. Notable users …

    Linux干貨 2016-12-16
  • 從增刪改查角度學習linux基礎命令

    從增刪改查角度學習linux基礎命令   本文從文件的增加、刪除、修改、查詢四個角度介紹linux的基本命令,介紹如下:   一.增 touch命令是最常用的創建文件的命令,它的常見參數如下: -a 或–time=atime或–time=access或–time=use  只更改存取時間。 -c 或&#…

    2017-07-15
  • 利用keepalived實現主/從和主/主模式的高性能負載均衡集群

    要求: 1、使用nginx的反向代理功能實現負載均衡 2、keepalived實現高可用 ???????第一組的虛擬地址為172.16.1.100 ????????????D設備的優先級高 ???????第二組的虛擬地址為172.16.1.110 ????????????E設備的優先級高 3、分別實現主/從和主/主兩種配置 集群拓撲: ? ? ? 第一種:主…

    2017-06-25
  • CentOS下獲取幫助

    CentOS中獲取幫助 在使用和學習CentOS系統時,我們可能會遇上不熟悉的命令,需要獲取幫助。在很多情況下,我們無法通過網絡獲取幫助,這個時候我們就需要自己通過查看系統幫助文檔來解決問題。下面就來介紹獲取幫助的方法: 1、 獲取簡單的幫助信息:whatis COMMAND   2、獲取比較詳細的命令幫助信息:help COMMAND;COMMA…

    2017-07-15

評論列表(1條)

  • luoweiro
    luoweiro 2017-02-23 07:40

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

欧美性久久久久