在开始今天的阅读之前,最好对python中的装饰器有个了解
在开始之前,有必要讲一下Python中装饰器的副作用,装饰器首先是针对函数来说的,它有很多作用,比如引入日志,函数执行时间的统计,执行函数之前预备处理,执行函数之后清理功能,权限校验等场景,缓存等等。除此之外,使用装饰器之后,还可以改变被装饰函数的说明文档,以及之后调用函数时函数在内存中的位置等等,今天要讲的就是如何通过functools工具包来消除装饰器的副作用。
1.好了,先来一段正常的代码(就是没使用functools工具包时的情况)
3 def note(func): #写一个装饰器
4 def inner():
5 'inner' #说明文档,后面调用__doc__时会打印
6 print('note---inner')
7 return func()
8 return inner
9
10 @note
11 def fun():
12 'fun'
13 print('I am fun')
14
15
16 fun() #调用已经装饰好的函数
17 print(fun.__doc__) #打印说明文档
18 print(fun)
运行上面代码之后,会打印如下结果
note---inner
I am fun
inner
<function note.<locals>.inner at 0x7f1f879e1f28>
主要看后面两行,首先打印的是说明文档,inner这个是我刚才在装饰器里面定义的,不信可以去翻看上面的代码,看装饰器里面的 内容,接下来你打印的是print(fun)的运行结果。先记住这两个,等下要和下面的使用functools之后的对比。
2.再看一下下面的代码,就是改了一点,仔细看你会发现区别的
1 import functools
2 def note(func): #写一个装饰器
3 @functools.wraps(func) #利用functool.wraps(func)消除装饰器的副作用
4 def inner():
5 'inner' #说明文档,后面调用__doc__时会打印
6 print('note---inner')
7 return func()
8 return inner
9
10 @note
11 def fun():
12 'fun'
13 print('I am fun')
14
15
16 fun() #调用已经装饰好的函数
17 print(fun.__doc__) #打印说明文档,未消除之前是inner,消除影响之后是原来的说明文档fun
18 print(fun)
其实主要来看第一行和第三行就行了,这两行就是导入了funtools工具包,好了,我们看一下这段代码的执行结果。
note---inner
I am fun
fun
<function fun at 0x7fe1d6088f28>
注意看后面两行和之前的区别,我猜你已经发现区别所在了,没错这样做的话,既能够对我们所要装饰的函数进行正常的装饰,而且还没有改变原函数的说明文档以及在内存中的位置。到这里,今天的内容就完了,是不是很简单呀!