比如現在有一百個函式,我們想給這100個函式加乙個新功能,我們肯定不能直接把原程式停了,然後一點一點修改源**。那麼這時候就要用到裝飾器了。
或者說裝飾器的作用就是 不修改源**以及原函式呼叫方式的情況下 給原函式增加新的功能。
原則總結成一句話:裝飾器對被裝飾的函式來說是透明的。
下面會講到,裝飾器本質是高階函式+巢狀函式。
1.函式就是「變數「的理解:
只要在函式執行前,定義過函式,執行就不會有錯
下圖是變數,函式在python儲存的概圖。
(大矩形表示python整個儲存空間。)
比如下面這段**,雖然 函式bar()是在 foo()之後定義的,但是只要是在 foo()執行之前 定義過了,就可以執行成功(記憶體中可以找到bar()對應的儲存空間)
再來乙個例子加深理解,下面我定義了乙個test函式。我直接輸入test,顯示的一串十六進製制數是記憶體位址。test相當於乙個」門牌號「,單獨輸數test是檢視這個門牌號是多少,輸入test()才是訪問門牌號對應的內容。
我讓fun = test,然後我直接fun()也可以執行(類似 上圖中x=1 y=x 那麼x,y都指向1)。到這裡,大家基本可以理解函式即變數的含義了吧。
2.高階函式:
高階函式兩個特點:
1.把乙個函式名當作實參傳給另外乙個函式
(作用:可以實現在不修改被裝飾函式源**的情況下為其新增功能)
如下圖
bar()函式 源**沒有改變,只是改變了呼叫方式:由 bar()→test1(bar) 給bar()增加了檢視程式執行時間的功能。
2.返回值中包含函式名。
(作用:可以實現不修改函式的呼叫方式)
3.巢狀函式
理解下面基本的巢狀函式樣例
注意bar()是不能在外面呼叫的,因為它是乙個內部函式,上面說了半天 函式即變數,所以把它看成乙個內部變數,它只存在於foo()函式執行的過程中。
注意:下面這樣的不算 巢狀函式,這是屬於函式的呼叫。巢狀函式必須得是用「def」 在函式中建立了函式。
示例一:
上面這段** timer()函式就是我們定義了乙個裝飾器,我們可以發現,它結合了巢狀函式與高階函式。
上面定義了兩個函式(被裝飾器裝飾的函式)
根據上面的知識,我們可以知道,用裝飾器給test1()函式增加功能時,需要這樣(上圖)呼叫。這樣就能保證裝飾器的規則:不改變函式源**;不改變函式呼叫方式。
其實我們說不改變函式呼叫方式,但其實呼叫的時候,呼叫的已經不是原函式了,test1已經換成了deco()
但是每次都這樣給乙個「與test1同名」的變數賦值就很麻煩,所以採用下圖方法:
再需要被裝飾(增加功能)的函式前加上**@裝飾器名** ,這個語句就相當於 test1=timer(test1)
因為可能被裝飾的函式 需要傳的引數數量不一定,比如 def test() 傳0個引數; def test(name,age) 需要傳2個引數,我們怎麼使裝飾器滿足這樣的可變需求的,看下面劃線部分**。加兩個非固定引數,這樣就能解決了。
python裝飾器理解 python裝飾器理解
裝飾器 在不改變原函式的 和呼叫方法的基礎上,給原函式增加額外的功能 理解宣告 為了方便理解,以下例子採用最簡潔的函式和新增的功能 給原函式新增乙個執行時間 import time def timer func def inner func return inner timer func timer...
python裝飾器 理解Python裝飾器
在python中,對於乙個函式,若想在其執行前後做點什麼,那麼裝飾器是再好不過的選擇,話不多說,上 usr bin env coding utf 8 script 01.py author howie from functools import wraps def decorator func wr...
python裝飾器理解 python裝飾器的理解
python裝飾器應該算是面試常考到的用點,之前在flask的應用中也是會常常用到,抽空仔細看書查資料理解了下裝飾器的概念,通過自己的理解記憶,應該對這個概念會有乙個大致上具體的了解。閉包說起python裝飾器,我們應該不得不談談閉包的概念。我對閉包的理解是,當函式存在巢狀,子函式呼叫了父函式的變數...