decorator的作用主要是给函数动态的添加功能,它接受一个函数作为参数,并且返回一个函数。
如定义一个能打印日志的decorator:
def log(func):
def wrapper(*args, **kw):
print('call %s():' % func.__name__)
return func(*args, **kw)
return wrapper
@log
def now():
print('2015-3-25')
以上则为now()添加了一个打印log的装饰器,调用now()并执行后输出:
>>> now()
call now():
2015-3-25
即传入的参数为now()方法,相当于执行now = log(now),即首先打印日志,然后执行原始函数。
如果decorator需要传参,则需编写一个返回decorator的高阶函数:
def log(text):
def decorator(func):
def wrapper(*args, **kw):
print('%s %s():' % (text, func.__name__))
return func(*args, **kw)
return wrapper
return decorator
@log('execute')
def now():
print('2015-3-25')
执行结果如下:
execute now():
2015-3-25
即相当于语句:
>>> now = log('execute')(now)
注意,使用decorator之后,函数的__name__等属性都会变为wrapper()函数的wrapper,有些依赖函数签名的代码执行就会出错,故需要最后一步,可以在wrapper前添加:@functools.wraps(func)
如:
import functools
def log(func):
@functools.wraps(func)
def wrapper(*args, **kw):
print('call %s():' % func.__name__)
return func(*args, **kw)
return wrapper
or
import functools
def log(text):
def decorator(func):
@functools.wraps(func)
def wrapper(*args, **kw):
print('%s %s():' % (text, func.__name__))
return func(*args, **kw)
return wrapper
return decorator