Python内置的包装装饰器的作用?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。
Python装饰器(decorator)在实现的时候,被装饰后的函数其实已经是另外一个函数了(函数名等函数属性会发生改变),为了不影响,Python的functools包中提供了一个叫包装的装饰来消除这样的副作用。写一个装饰的时候,最好在实现之前加上functools的包装,它能保留原有函数的名称docstring和。
<强>包装内置方法的作用强>
查看一个函数的帮助文档有两种方法:
func_name.__doc__ 帮助(func_name)
先来看一个例子,定义timmer装饰器和指数函数,并且都添加了帮助文档。
import 时间 def timmer(函数): ,,,def 内部(* args, * * kwargs): ,,,,,,,& # 39;wrapper inner 函数# 39; ,,,,,,,start_time=time.time () ,,,,,,,res=func (* args, * * kwargs) ,,,,,,,end_time=time.time () ,,,,,,,印刷(时间:“run % s “, % (end_time-start_time)) ,,,,,,,return res ,,,return 内部 def 指数(): ,,,& # 39;index 函数# 39; ,,,time . sleep (2) ,,,print (“welcome 用index page")
在指数没有被timmer装饰前,来查看指数的帮助文档:
打印(index.__doc__)
程序运行结果:
index 函数
然后为指数添加timmer装饰器,再次查看指数函数的帮助文档:
import 时间 def timmer(函数): ,,,def 内部(* args, * * kwargs): ,,,,,,,& # 39;wrapper inner 函数# 39; ,,,,,,,start_time=time.time () ,,,,,,,res=func (* args, * * kwargs) ,,,,,,,end_time=time.time () ,,,,,,,印刷(时间:“run % s “, % (end_time-start_time)) ,,,,,,,return res ,,,return 内部 @timmer def 指数(): ,,,& # 39;index 函数# 39; ,,,time . sleep (2) ,,,print (“welcome 用index page") 打印(index.__doc__)
程序运行结果:
wrapper inner 函数
可以看的到,在为指数函数添加装饰器后,指数函数的帮助文档变成装饰器timmer内部函数的帮助文档了。
换句话说,就是原始指数函数内部的数据被装饰器timmer修改了。
怎么样才能在保留原始被装饰函数的数据的前提下,为函数添加新功能呢? ?就是python内置的包装装饰器。
导入包装装饰器,修改上面的代码,为timmer的内部函数添加包装装饰器,然后再次查看被装饰函数的帮助文档:
import 时间 得到functools import 包装 def timmer(函数): ,,,@wraps(函数) ,,,def 内部(* args, * * kwargs): ,,,,,,,& # 39;wrapper inner 函数# 39; ,,,,,,,start_time=time.time () ,,,,,,,res=func (* args, * * kwargs) ,,,,,,,end_time=time.time () ,,,,,,,印刷(时间:“run % s “, % (end_time-start_time)) ,,,,,,,return res ,,,return 内部 @timmer def 指数(): ,,,& # 39;index 函数# 39; ,,,time . sleep (2) ,,,print (“welcome 用index page") 打印(index.__doc__)
运行程序,执行结果如下:
index 函数
可以看的到,指数函数即使添加了装饰器,其内部的原始数据仍然没有被装饰器修改。
从上面的示例可以看的出,包装装饰器的作用就是保留被装饰对象的原始数据信息。
<强>实例一:强>
不加包装
#,- *安康;编码=utf-8 - *安康; 得到functools import  wraps ,, def my_decorator(函数): ,,,def 包装器(* args,, * * kwargs): ,,,,,,,& # 39;& # 39;& # 39;装饰# 39;& # 39;& # 39; ,,,,,,,印刷(& # 39;Calling  decorated 函数……& # 39;) ,,,,,,,return func (* args,, * * kwargs) ,,,return wrapper , , @my_decorator def 示例(): ,,,“““Docstring"““, ,,,print (& # 39; nbsp; example 函数# 39;) 打印(example.__name__, example.__doc__)
执行结果:
(& # 39;包装# 39;,,& # 39;装饰# 39;)
<强>实例二:强>
加包装