装饰器给我们带来高效的编程,但也会产生一些问题,而这些问题又容易被我们大家忽视。
在Python世界里,一切皆对象,所以函数也是对象,函数有一些内置属性,例如:__name__、 __module__ 、__doc__ 和__dict__等。
如果使用装饰器修饰函数,那么函数的内置属性值会发生变化,这将不利于调试,定位bug位置,这就是装饰器产生的副作用!
结合示例了解装饰器的副作用:
定义了两个测试函数,功能一致,函数sum_test1用aop装饰器修饰(这里装饰器没有任何功能操作),函数sum_test2没有装饰器修饰。
看代码执行结果:
你会发现:被装饰器修饰的函数,属性内容发生了改变,sum_test1函数的__name__、__doc__等等属性值都变成了装饰器函数对应属性值,而没有装饰的sum_test2函数显示正常!
更大的问题了,被装饰器修饰的多个函数,其函数属性值都会变成装饰器函数内容,多个不同的函数,其属性值是相同的,这非常不利于调试,定位程序bug。
以上就是装饰器产生的副作用!
使用functools模块提供 wraps和update_wrApper 方法能够修正函数内置属性值,消除装饰器副作用
update_wrapper 使用示例:
看代码执行结果:
wraps使用示例:
update_wrapper和wraps方法的功能是一样的,只不过wraps是使用partial()对update_wrapper进一步封装得到的,所以推荐使用wraps方法!
使用装饰器给我们带来高效的编程,但是装饰器会产生一个容易让人忽视的副作用:不利于调试,定位程序bug。
使用functools模块提供 wraps和update_wrapper 方法,消除Python装饰器副作用;而且使用update_wrapper和wraps是一个好的编程习惯!