def w1(func): def inner(): # 驗證1 # 驗證2 # 驗證3 return func() return inner @w1 def f1(): print 'f1' @w1 def f2(): print 'f2' @w1 def f3(): print 'f3' @w1 def f4(): print 'f4'
裝飾器原理
def w1(func): def inner(): # 驗證1 # 驗證2 # 驗證3 return func() return inner @w1 def f1(): print 'f1'
當寫完這段代碼後(函數未被執行、未被執行、未被執行),python解釋器就會從上到下解釋代碼,步驟如下:
沒錯,從表面上看解釋器僅僅會解釋這兩句代碼,因為函數在沒有被調用之前其內部代碼不會被執行。
從表面上看解釋器著實會執行這兩句,但是 @w1 這一句代碼裡卻有大文章,@函數名 是python的一種語法糖。
如上例@w1內部會執行一下操作:
執行w1函數,並將 @w1 下面的 函數 作為w1函數的參數,即:@w1 等價於 w1(f1)
所以,內部就會去執行:
def inner:
#驗證
return f1() # func是參數,此時 func 等於 f1
return inner # 返回的 inner,inner代表的是函數,非執行函數
其實就是將原來的 f1 函數塞進另外一個函數中
將執行完的 w1 函數返回值賦值給@w1下面的函數的函數名
w1函數的返回值是:
def inner:
#驗證
return 原來f1() # 此處的 f1 表示原來的f1函數
然後,將此返回值再重新賦值給 f1,即:
新f1 = def inner:
#驗證
return 原來f1()
所以,以後業務部門想要執行 f1 函數時,就會執行 新f1 函數,在 新f1 函數內部先執行驗證,再執行原來的f1函數,然後將 原來f1 函數的返回值 返回給了業務調用者。
如此一來, 即執行了驗證的功能,又執行了原來f1函數的內容,並將原f1函數返回值 返回給業務調用著
一個參數
def w1(func): def inner(arg): # 驗證1 # 驗證2 # 驗證3 return func(arg) return inner @w1 def f1(arg): print 'f1'
倆個參數
def w1(func): def inner(arg1,arg2): # 驗證1 # 驗證2 # 驗證3 return func(arg1,arg2) return inner @w1 def f1(arg1,arg2): print 'f1'
可以裝飾具有處理n個參數的函數的裝飾器?
def w1(func): def inner(*args,**kwargs): # 驗證1 # 驗證2 # 驗證3 return func(*args,**kwargs) return inner @w1 def f1(arg1,arg2,arg3): print 'f1'