简单装饰器
本质上,decorator就是一个返回函数的高阶函数。所以,我们要定义一个能打印日志的decorator,可以定义如下:
def log(func):
def wrapper(*args, **kw):
print('call %s():' % func.__name__)
return func(*args, **kw)
return wrapper
实际使用时把decorator置于函数的定义处:
@log
def now():
print('2020-6-23')
#相当于执行了now = log(now),即将log()函数返回的wrapper函数赋值给新变量now
>>> now()#相当于执行命令wrapper()
call now():
2020-6-23
带参数装饰器
def log(text):
def decorator(func):
def wrapper(*args, **kw):
print('%s %s():' % (text, func.__name__))
return func(*args, **kw)
return wrapper
return decorator
这个3层嵌套的decorator用法如下:
@log('execute')
def now():
print('2020-6-23')
#相当于执行了now = log('execute')(now)
保持原函数__name__属性不变
以上写法由于将返回的wrapper函数赋值给新变量now,所以其__name__属性已经从原来的’now’变成了’wrapper’:
>>> now.__name__
'wrapper'
需要用Python内置的functools.wraps把原始函数的__name__等属性复制到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
带参数装饰器
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
参考文章:
https://www.liaoxuefeng.com/wiki/1016959663602400/1017451662295584