注意:我们要借助Python的@语法,把decorator置于函数的定义处
初步尝试:
def log(func):
def wrapper(*args, **kw):
print 'begin call: %s' %func.__name__
return func(*args, **kw)
print 'end call: %s' %func.__name__
return wrapper
@log
def now():
print '2018-06-21'
now()
结果不如预期~:
打印的日志都在函数运行之前
这是因为函数只在返回时调用,如果能调用后,加一句日志,再返回,就可以了。
更改如下:
def log(func):
def wrapper(*args, **kw):
print 'end call: %s' %func.__name__
c = func(*args, **kw)
print 'begin call: %s' %func.__name__
return c
return wrapper
@log
def now():
print '2018-06-21'
now()
调用的装饰器log中,函数wrapper里将now()函数赋值给C,相当于调用了一次now(),再加上最后的日志,而最后返回的是c,一样是now函数
测试:
成功
-------------------------------------------------------------------------
再思考一下能否写出一个@log
的decorator,使它既支持:
@log
def f():
pass
又支持:
@log('execute')
def f():
pass
import functools
def log(text = ''):
def decorator(func):
def wrapper(*args, **kw):
print '%s end call: %s' %(text, func.__name__)
c = func(*args, **kw)
print '%s begin call: %s' %(text, func.__name__)
return c
return wrapper
return decorator
@log()
def now():
pass
now()
测试:
只需将代码中的@log()后参数换成‘execute’即可测试,结果如下图右,成功。