理解Python的装饰器分为以下6步
- 首先先理解装饰器的含义。装饰器本质上是一个 Python 函数或类,它可以让其他函数或类在不需要做任何代码修改的前提下增加额外功能,装饰器的返回值也是一个函数/类对象。 有了装饰器,我们就可以抽离出大量与函数功能本身无关的雷同代码到装饰器中并继续重用。
- 然后了解下最简单的装饰器,也就是无函数参数的装饰器
def use_logging1(func):
def wrapper():
logging.warn("%s is running" % func.__name__)
return func()
return wrapper
@use_logging1
def foo1():
print("i am foo")
- 带函数参数的函数的装饰器
def use_logging2(func):
def wrapper(*args, **kw):
logging.warn("%s is running" % func.__name__)
return func(*args, **kw)
return wrapper
@use_logging2
def foo2(name):
print("i am %s" % name)
- 带函数参数+带装饰器参数的函数的装饰器
def use_logging3(text):
def use_logging2(func):
def wrapper(*args, **kw):
logging.warn("%s is running with %s " % (func.__name__, text))
return func(*args, **kw)
return wrapper
return use_logging2
@use_logging3("decorator's args")
def foo3(name):
print("i am %s" % name)
- 因为函数也是对象,它有__name__等属性,但你去看经过decorator装饰之后的函数,它们的__name__已经从原来的’now’变成了’wrapper’,有了functools.wraps()我们就不需要把原始函数的__name__等属性复制到wrapper()函数中,它就是专门干这事的。如下代码块中的foo1.__name__仍然为foo1
def use_logging1(func):
@functools.wraps(func)
def wrapper():
logging.warn("%s is running" % func.__name__)
return func()
return wrapper
@use_logging1
def foo1():
print("i am foo")
- 应用:写一个对任何函数的执行进行计时的装饰器
def funcTiming(func):
@functools.wraps(func)
def wrapper():
print("begin call")
begin = time.time()
result = func()
end = time.time()
print("end call")
print('%s executed in %s ms' % (func.__name__, end - begin))
return result
return wrapper
@funcTiming
def func():
print("running")