零,装饰器能够在函数执行前后运行一些附加代码,使得开发者可以在装饰器中访问并修改原函数的参数,以及返回值,以实现约束语义,调试程序,注册函数等目标
一,普通装饰器
def log(func):
def wrapper(*args,**kwargs):
print('函数执行前执行')
return_data = func(*args,**kwargs) #运行函数
print('函数执行后执行')
return return_data
return wrapper
#装饰器会自动传入当前函数引用作为参数
@log #此处相当于执行test=log(test)
def test(): #也就是说,此时执行的不是test而是wrapper
print("函数执行中")
return "函数返回值"
print(test())
二,带参数的装饰器
def log(text):
def decorator(func):
def wrapper(*args,**kwargs):
print('函数执行前执行')
print(text)
return_data = func(*args,**kwargs)
print('函数执行后执行')
return return_data
return wrapper
return decorator
#装饰器会先传入参数,再对返回的函数传入装饰的函数引用
@log('execute') #此处相当于执行test=log('execute')(test)
def test(): #也就是说,此时执行的不是test而是wrapper
print("函数执行中")
return "函数返回值"
print(test())
三,注意:wrapper函数名是'wrapper','module'模块也可能会出问题,有些依赖原始函数签名的函数执行会出错,有两种解决方法
- 编写
wrapper.__name__=func.__name__
- 使用内置的functools.wraps,先
import functools
,然后在每个def wrapper
上面添加@functools.wraps(func)
即可,它会把内部函数相关的重要元数据全部复制到外围函数
四,可以将装饰器套在递归函数上打印信息