今天学习Pyhton学到了装饰器,但是遇到视频无法播放,附带源码中有一个functools.wraps()的装饰器,看了好久做了实验才知道是干什么的。
先看一下functool.wraps的定义以及阐述(由于我用的是虚拟机,所以只能上图片不能上代码了):
大概意思是说,这个函数返回一个装饰器,调用update_wrapper()函数,和装饰器一起作为wraps()的剩余的参数,默认参数是和update_wrapper()的相同,后面大概意思是这个是个简单的函数去应用partial()和update_wrapper().(英语不好,只能翻译出大概。见谅见谅。)
在functools的源文件代码中,有这样的说明:
大概意思是说:update_wrapper()和wraps()是帮助编写可以处理naive内省的包装器功能的工具。原谅我的英语不好,这里的naive翻译不出来,我只知道它的天真的意思。
而wraps的参数是这样定义的:
表明,这个函数(functool.wraps)只会对这几个属性起作用,而这些属性都是我们非常熟悉的,比如__doc__属性,我们可以用来查看帮助文档,从wraps的文档中,我猜测这个函数应该有partial()类似的功能。
我们知道,python中partial()函数可以给某带参数的函数的参数绑定一个默认值,调用的时候就无须传递参数了,那么,这个函数(functool.wraps())是不是可以起到类似于绑定的作用,但是绑定的是源文件的私有属性。
当装饰器装饰一个函数时,实际上就是将被装饰的函数作为一个参数传入装饰器函数,返回一个闭包,而闭包内部调用这个函数,再另外多做一些事情。然后再由我们的函数名字去接收那个返回值的闭包的引用,达到了我们装饰的目的,所以此时,我们的函数的__name__等属性其实已经改变,变成了我们闭包的私有属性。
怀着试试看的态度,我写了以下代码,得出了如下的结果:
可见,这个函数确实是将被装饰函数的__name__以及__doc__等属性绑定到了原函数的上面。我把那个闭包的装饰器
@functools.wraps(func)
删除掉,出现这样的结果:
所以,我得出这样的总结:
functools.wraps()这个函数,作为一个装饰器去装饰闭包,并且给这个装饰器传入一个参数,这个参数是闭包外的装饰器装饰的那个外部的被装饰函数,此时,外部我们的自定义的函数的私有属性如__name__、__doc__等还是为我们自定义的函数本身的私有属性,而不会变成闭包的私有属性。
谢谢大家看完,小白理解浅陋,还望各位指出问题所在。