Python中的装饰器
文章目录
- 装饰器
- 普通装饰器
- 带参数的装饰器
- 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 data
return rela_func
return 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 wraps
def 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 data
return rela_func
return decorator_func_rel
if __name__ == '__main__':
print(ldsx_fun_new.__name__)
# 返回内容为ldsx_fun_new