在了解裝飾器的之前一定要先了解函數作為參數傳遞, 什么是函數內嵌,請參考我之前寫的博客函數簡介
因為在python里面,函數也是對象,也可以作為參數進行傳遞.python裝飾器本質也是一種特殊函數,它接收的參數是函數對象,然后動態地函數參數添加額外的功能,而不用修改原有的函數對象.python裝飾器傳入的參數是函數,返回的值也是函數!
python裝飾器思想有點類似設計模式的裝飾模式, 其意圖是動態地給函數對象添加額外的功能.比如像增加日志打印的功能,有點面向切面編程(AOP)的感覺.
裝飾器語法
以@開頭,接著后面跟著的是裝飾器的名字和可選的參數.裝飾器語法是一種語法糖.
格式如下
實例
@deco
def foo():
print 'In foo'
foo()
foo()
內嵌函數保證每次新函數都被調用.而且被裝飾的函數可以帶有參數.
實例
@deco
def foo(x):
print 'In foo, get value is: %d' % x
foo(123456)
需要自己返回以函數作為參數的裝飾器。換句話說,decomaker()用 deco_args 做了些事并返回函數對象,而該函數對象正是以 foo 作為其參數的裝飾器。簡單的說來:foo=decomaker(deco_args)(foo)
實例
def wrapper2(func):
def _deco(x):
func(x)
print "get type is: ", arg
return _deco
if arg == 'type1':
return wrapper1
else:
return wrapper2
@deco("type2")
def foo(x):
print 'In foo: ', x
foo(123)
裝飾器本質是高階的函數,可以裝飾其他函數,增加被裝飾函數的功能,但不能覆蓋或改變被裝飾函數原有的行為.對于被裝飾的函數來說,裝飾器是透明的.裝飾器傳入參數為函數,返回的函數是被裝飾的函數.最后我們來實現給一個函數添加打印日志的功能,而不用改變這個函數.
def log(prefix, suffix):
def deco(func):
@functools.wraps(func)
def wrapper(*args, **kargs):
print '%s log start' % prefix
print('get a is: %s' % args[0])
print('get b is: %s' % args[1])
print('get c is: %s' % args[2])
print('get d is: %s' % kargs['d'])
print('get d is: %s' % kargs['f'])
func(*args, **kargs)
print '%s log end' % suffix
return wrapper
return deco
@log('logstart', 'logend')
def test(a, b, c, d, f):
print 'call func name is: %s' % test.__name__
test(1, 2, 3, d = 'dddd', f = 'ffff')
新聞熱點
疑難解答
圖片精選