裝飾器的語法以@開頭,接著是裝飾器函式的名字、可選引數。
緊跟裝飾器宣告的是被裝飾的函式和被裝飾的函式的可選引數,如下:
@decorator(dec_opt_args)
def func(func_args):
....
其實總體說起來,裝飾器其實也就是一個函式,一個用來包裝函式的函式,裝飾器在函式宣告完成的時候被呼叫,呼叫之後宣告的函式被換成一個被裝飾器裝飾過後的函式。
如:
def deco(func): ... return func @deco def foo(): print 'foo' #----------------------------------- #等價如下: def deco(func): ... return func def foo(): print 'foo' foo = deco(foo) 如下例子: def deco1(func): print 'ok' return func @deco1 def foo(): print 'foo' foo() #輸出-------------- #ok #foo #------------------
如果不使用裝飾器,則可如下:
def deco1(func): print 'ok' return func def foo(): print 'foo' print foo #<function foo at 0x00AFE6F0> foo = deco1(foo) foo() #輸出-------------- #ok #foo #------------------
兩者對比下,可發現使用裝飾器是那麼簡便、靈活。特別是在企業級的開發上。
同時也可以多個裝飾器重疊使用:
def deco1(func): print 'deco1' return func def deco2(func): print 'deco2' return func @deco1 @deco2 def foo(): print 'foo' foo() #輸出如下:----------- #deco2 #deco1 #foo #---------------------
等效於:
@deco1 @deco2 def foo(arg):pass -----------與下等效---------- foo = deco1(deco2(foo()))
二、有參、無參的裝飾器
上面的例子基本上都是有引數的,無引數更為簡單。
1、無參
@deco1
@deco2
def foo(arg):pass
---------------------
foo = deco1(deco2(foo()))
2、有參
@deco1(deco_arg)
@deco2
def foo(arg):pass
---------------------
foo = deco1(deco_arg)(deco2(foo()))
返回以函式作為引數的裝飾器
三、用處
1、引用日誌
2、增加計時邏輯來檢測效能
3、給函式加入事務的能力
四、例項
from time import ctime,sleep def deco(func): def decoIn(): print '[%s]:%s called' %(ctime(),func.__name__) return func return decoIn @deco def foo(): pass foo() sleep(4) for i in range(2): sleep(1) foo() #輸出如下:-------- #[Fri Jul 05 10:45:04 2013]:foo called #[Fri Jul 05 10:45:09 2013]:foo called #[Fri Jul 05 10:45:10 2013]:foo called #------------------