今天回顧了一下裝飾器知識,來記錄一下個人的體悟.
看了幾個大神的部落格,對裝飾器的解釋如下:
假設我們要增強函式的功能,比如,在函式呼叫前後自動列印,但又不希望修改函式的定義,這種在**執行期間動態增加功能的方式,稱之為「裝飾器」(decorator)。
我個人覺得說的太籠統,因為我下面的**完成了上述的要求卻不能稱之為裝飾器:
#傳統意義的裝飾器
def new(func):
print('############')
return func(*args, **kw)
#定義乙個求和函式,再用@new對它進行裝飾
@new
def add(a,b):
print(a+b)
pass
#功能與上面的一樣,只是當要裝飾其它函式時需要把函式作為引數傳入,顯得麻煩,所以我們需要傳統裝飾器
def myadd(*args, **kw,func=add):
print('############')
return func(*args, **kw)
我查閱資料得知裝飾器的原則組成如下:
< 函式+實參高階函式+返回值高階函式+巢狀函式+語法糖 = 裝飾器 >
這是裝飾器的靈魂,我個人的理解為,裝飾器必須滿足他所規定的巢狀函式的結構,因為這樣才能使用@的語法糖,而**@語法糖**才是裝飾器的優點所在.
@語法糖到底是怎麼實現的呢?
以上面**為例來進行說明,給add函式加上@new裝飾器其實等同於以下的**
add = new(add)
理解了普通裝飾器的規範和原理再來理解可以用裝飾器傳參的decorator的高階函式就水到渠成了.結構如下:
def new(text):
def decorator(func):
print('####',text,'####')
return func(*args, **kw)
return decorator
使用方法如下:
@new('為所欲為')
def add(a,b):
print(a+b)
pass
#執行add(1,2)結果如下:
#### 為所欲為 ####
3
同理,用@new( c )裝飾add等同於:
add=new(c)(add)
到這裡可能會產生疑問:我們要實現用裝飾器傳遞引數就必須用到三層函式的結構嗎?套在最外的一層將所有需要的引數一次性傳遞進去不可以嗎?
答案是肯定得用三層結構的,因為一次傳幾個引數,其中有的引數我們只想設定一次,但是因為有的引數必須每次執行時都得設定,導致前者也必須得每次設定.而裝飾器每層函式傳乙個引數的結構使得它可以完成某些引數只設定一次的需求.
有一天,我的乙個朋友對我說:裝飾器只能在被修飾的函式前新增操作.
我想應該也有些初學者和我朋友有著同樣錯誤的想法.
我朋友的理由是被裝飾的方法是最後return才被呼叫的.乍一聽好像有點道理,其實這是沒理解裝飾器的原理,只會生搬硬套造成的.
前面我們知道了裝飾器可以理解為構造了乙個新的warpper方法,只是把add函式放了進去而已,至於說放**,這完全是你說了算,沒必要死板的用return來呼叫,**如下:
def new(func):
print('--------------------------')
func(*args, **kw)
print('************************')
pass
@new
def add(a,b):
print(a+b)
pass
add(2,3)
#執行結果如下
--------------------------
5************************
Python裝飾器的原理與應用
裝飾器是什麼東西呢?就是起到裝飾作用的這麼乙個函式,那這玩意有啥用呢?很多人都會丟擲這樣的疑問,咱們就通俗的說一下這個裝飾器到底是什麼東西,是什麼工作原理呢?首先,裝飾顧名思義就是裝飾用,為什麼需要對函式裝飾呢?是因為要遵循乙個 開放 封閉 原則,因為已經寫好的函式可能已經經過很久的測試和應用,沒有...
python裝飾器原理 Python裝飾器原理
裝飾器 decorator 是物件導向設計模式的一種,這種模式的核心思想是在不改變原來核心業務邏輯 的情況下,對函式或類物件進行額外的修飾。python中的裝飾器由python直譯器直接支援,其定義形式如下 decorator def core service 要理解上述 的含義,我們從自定義函式裝...
python 裝飾器應用
裝飾器應用 裝飾器的主要作用是 列印日誌,檢測效能,資料庫事物,url路由 應用1,生成標籤 def bold fn def 閉包,這個函式的作用就是給原來的函式增加一些功能,return fn bold deftest return python in 2 test out 2 python 等價...