这是一篇关于python装饰器的博文
在学习python的过程中处处受阻,之前的学习中Python的装饰器学习了好几遍也没能真正的弄懂。这一次抓住视频猛啃了一波,就连python大佬讲解装饰器起来也需要大半天的时间。据说是两个老师轮流讲解,还得吃药才能讲完。详情请见老男孩的第14期视频day4。
听完两位老师的讲解,我算是系统而又全面的理解了装饰器,并将其总结。
一、定义
想要彻底的弄清楚装饰器,就得彻底的弄明白Python装饰器的定义,百科里的定义说:装饰器是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的有插入日志、性能测试、事务处理等。装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量函数中与函数功能本身无关的雷同代码并继续重用。之前的都是扯淡,具体的等深入后才能了解,我们目前只需要明白装饰器的作用就是为已经存在的对象添加额外的功能。
简单来说,装饰器的作用就是给已经存在的函数附加功能。
二、原则
做任何事都需要讲究原则。编写装饰器也需要按照相应的原则出现,如果不遵守其原则就不能算是装饰器。
装饰器的原则:
A、不能修改被装饰函数的源代码
B、不能修改装饰器的函数的调用方式
图2.1需求
图2.2修改一
如图2.2中的foo()函数。虽然实现了图2.1中所需求的功能,但是图2.2中的foo修改了代码,这便违反了装饰器原则一,不能称之为装饰器。
图2.3修改二
如图2.3中的test()函数。它也实现了图2.1中所需求的功能,但是图2.3中需要调用test()函数才能实现其功能,这样就违反了原则二(如果程序中有一千个foo函数就得将这1000个foo全改成test),这么修改也不能称之为装饰器。
三、掌握装饰器所需的知识储备
想要掌握python的装饰器,就得先掌握如下知识作为掌握装饰器成储备知识:
1、函数即“变量”(一切皆对象)
2、高阶函数
3、嵌套函数
只有掌握了这三个知识,才能掌握装饰器。
3.1 函数即“变量”(一切皆对象)
在python中,一切皆对象(这就是为什么这么多屌丝来学python的原因)。变量是对象,函数是对象,类是对象,所有的一切都是对象。如图3.1所示,这里定义函数func,于是内存中就开辟属于func的内存空间,写入func的函数功能。随后在解释器上输入func函数的函数名,这时会返回一串指针地址,在python中所有的对象都会对应的指针地址,即指向内存中func函数的位置。如果在func函数名后加上(),这就说明func根据指针地址调用了func函数。
如图,将func函数的变量名赋值给f,就是将func的内存地址赋值给f,f就会指向内存红func函数的位置。在解释器中输入f()时,就能调用对应地址的func函数。
图3.1一切皆对象
3.2高阶函数
高阶函数即一个函数的函数名作为参数传入另一个函数。如图3.2所示。定义func函数有x,y,f三个参数,执行func函数时将实参abs(abs是求绝对值的内置函数)传形参f,func函数最后return两数的绝对值和。
图3.2高阶函数
3.3嵌套函数
嵌套函数是在一个函数的函数体内声明一个函数,再调用
图3.3嵌套函数
四、装饰器初成
如图4.1所示,这样写就能够实现图2.1中的需求,并且遵循了装饰器的两个原则。其中就涉及到了装饰器的三个储备知识,由此可见三个储备知识的重要性。
图4.1装饰器初成
但是图4.1中的test只是刚好装饰没有返回值的函数,如图4.2则可以装饰存在返回值的函数。
图4.2装饰器初成修改
五、装饰器小成
四中描述的装饰器还不够全面,如果函数foo需要传入参数时,图4.2中的装饰函数就会报错。于是这里就涉及到了函数的可变长参数和可变长关键字参数。这样就能实现任意的参数传入。于是装饰器的功法就小有所成了。如图5.1所示。
图5.1装饰器小成
六、装饰器大成
其实装饰器学到五的时候,我就觉得已经很厉害了,想着自己终于弄懂了,但是老男孩里的alex老师有继续补充了一个关于装饰函数传参的知识点,突然间我就觉得这节课值500块,感谢Alex老师。老师最后的代码是这样的。这是一个模拟网站不同登陆方式的装饰器,使用一个装饰器,对不同的函数的附加不同的功能。Home函数使用密码登陆方式,bbs函数使用另一种登入方式(此处只是模拟一下),如图6.1所示。
图6.1装饰器大成
七、总结
以上就是我学习装饰器之后对其的总结,根据上述内容,我绘制了一个概念图,便于对装饰器的理解和掌握。