参考: http://www.runoob.com/w3cnote/python-func-decorators.html
装饰器(Decorators)本质上是一个 Python 函数或类,它可以让其他函数或类在不需要修改原有代码的前提下增加额外功能,装饰器的返回值也是一个函数/类对象。它可以让你在一个函数的前后去执行代码。
经常用于有切面需求的场景,比如:打印日志、性能测试、事务处理、缓存、权限校验等场景。
以打印日志为例
from datetime import datetime
def log(func):
def wrapper(*args, **kw):
print('call %s():' % func.__name__)
return func(*args, **kw)
return wrapper
@log
def cal_time():
print(datetime.now())
把@log放在cal_time()前面相当于执行了
log(cal_time)
当然,log函数也可以传入参数,这是就是三层函数了
def log(txt):
def dec(func):
def wrapper(*args, **kw):
print('%s call %s():' % (txt, func.__name__))
return func(*args, **kw)
return wrapper
return dec
@log("log")
def cal_time():
print(datetime.now())
相当于
log("log")(cal_time)
但这是打印cal_time.__name__会发现函数名不是cal_time,是因为装饰器重写了函数的名字和注释文档(docstring),幸运的是Python提供给我们一个简单的函数来解决这个问题,那就是functools.wraps。因此上述代码可修改为
from functools import wraps
def log(text):
def decorator(func):
@wraps(func)
def wrapper(*args, **kw):
print('%s %s():' % (text, func.__name__))
return func(*args, **kw)
return wrapper
return decorator
@log("log")
def cal_time():
print(datetime.now())
print(cal_time.__name__)
除了在函数中装饰外,还有一种类装饰器
class Foo(object):
def __init__(self, func):
self._func = func
def __call__(self):
print(self._func.__name__)
print(self._func.__doc__)
print ('class decorator runing')
self._func()
print ('class decorator ending')
@Foo
def bar():
"document instruction"
print ('bar')
bar()
基本网上找到的资料,目前还不是理解很彻底