厦门旅游网站设计厦门网站seo哪家好
文章目录
- 装饰器
- 普通装饰器
- 带参数的装饰器
- warps 保持函数源信息不变
装饰器
普通装饰器
原理就是闭包,被装饰器装饰的函数,通过闭包返回新的函数内存地址
from functools import wraps# 不进行装饰
def ldsx():print('执行过程')return 'Data'# fun就是被装饰的函数名
def decorator_func(fun):def rela_func(*args,**kwargs):data = fun()data+='_扩展'print('执行过程扩展')return data# 返回函数名return rela_func# 使用装饰器装饰
@decorator_func
def ldsx_fun():print('执行过程')return 'Data'if __name__ == '__main__':data = ldsx()print(data)data = ldsx_fun()# 查看返回值,并且查看ldsx_fun的实际函数名print(data,ldsx_fun.__name__)# 非装饰器原始
# 执行过程
# Data
# 使用装饰器
# 执行过程
# 执行过程扩展
# Data_扩展 rela_func
调用ldsx_func
()可以写成decorator_func(ldsx_fun)()
decorator_func(ldsx_fun)
等价于 rela_func
然后再调用rela_func()
,所以使用 ldsx_fun()
,相当于使用rela_func()
带参数的装饰器
def decorator_func_args(ags):def decorator_func_rel(fun):def rela_func(*args,**kwargs):data = fun(*args,**kwargs)data+='_扩展'print('执行过程扩展')if ags == 'ldsx':print("装饰器参数开启 增加此扩展")return datareturn rela_funcreturn decorator_func_rel@decorator_func_args('ldsx')
def ldsx_fun_new(a,b):print('执行过程')print(a+b)return 'Data'if __name__ == '__main__':data = ldsx_fun_new(1,2)print(data, ldsx_fun_new.__name__)#打印
'''
执行过程
3
执行过程扩展
装饰器参数开启 增加此扩展
Data_扩展 rela_func
'''
装饰器函数多一层,用于接受装饰器参数,其余逻辑与普通装饰器一致
相当于decorator_func_args(‘ldsx’) -->decorator_func_rel(ldsx_fun_new)–>rela_func(1,2)
warps 保持函数源信息不变
由上文可见最后的函数名称其实都已经变了 如 ldsx_fun_new._name_ 得到的函数名rela_func
from functools import wrapsdef decorator_func_args(ags):def decorator_func_rel(fun):# warps会保持fun的元数据不变 @wraps(fun)def rela_func(*args,**kwargs):data = fun(*args,**kwargs)data+='_扩展'print('执行过程扩展')if ags == 'ldsx':print("装饰器参数开启 增加此扩展")return datareturn rela_funcreturn decorator_func_relif __name__ == '__main__':print(ldsx_fun_new.__name__)
# 返回内容为ldsx_fun_new