一、引言
最近做了一个小小小项目,写了一些偏工程的代码。项目的目的看起来很简单,就是去组里的一个能显示调试信息网站上,根据我们提供的一堆查询,获取调试信息的response,然后离线的解析来完成后续实验。为啥要做这个呢,说是在访问服务的时候增加了一个鉴权的过程,带来了更为安全的访问过程,所以就导致之前的访问代码需要更新才能继续使用。之前的代码是Java的,相比之下使用Python更为灵活,所以这次我用Python进行了实验。
当然,以上不是重点,不然这篇就成了项目复盘了。促使我完成这篇博客的契机,是我在开发过程中阅读了一位大佬的代码,读完之后着实有感,其中让我感受最深的就是大佬的Python装饰器的使用,他将一个有记录权限是否超时功能的装饰器放在获取信息的函数前,进而可以自动的完成权限的刷新和复用,很是巧妙。于是,我重新对Python装饰器进行了学习,期间让我产生了一个疑问,Python装饰器又强大又巧妙,那么它的使用是让我的代码更轻了还是更复杂了呢?
本文首先给大伙简单熟悉一下装饰器这个工具的原理,然后对其进行一个从应用场景和个人使用上的讨论,希望能对大家有一些小小的帮助。
二、Python装饰器的介绍
1. Python装饰器定义
“简单地说,Python装饰器是修改其他函数的功能的函数”[①]。
这说得确实有点简单,我个人理解的话,装饰器的目的就是在运行某一个函数的前后,再对函数进行一个补充,我这里画了一个图来进行解释。
上图是一个最简单的、在装饰器中没有额外输入的用法。可以看到修改过程中,我们将两个函数fun1和fun2中相同的功能(xx)进行了抽取,组装成了一个装饰器函数decorator,同时,将不同的功能A和功能B进行剥离,成为更加简洁的两个小函数,最后,将装饰器和功能进行组合,获得了修改后的版本。(代码量就这样下去了,有木有)
2. Python装饰器和函数的关系
装饰器本质上就是一个函数,它的输入是要进行补充的函数,输出的则是补充后的函数,在使用上更加灵活,可以直接在定义函数的上一行进行添加,而不用在使用时额外的定义,整个过程看起来更加的优雅。
三、讨论
我之前也多少看过一些Python装饰器的使用说明,却一直没有用起来,现在想想,一是因为自己图开发的方便,因为很少涉及到工程项目,写几个类基本就能解决数据的处理,复用这块也是能用函数就用函数替代;二是因为读码理解难,阅读装饰器代码在逻辑上需要一定的抽象力,才能把函数的跳转看明白。
现在重新回头又学了一遍装饰器,我的感觉依旧没变,如果在我平时所接触的任务的编码中使用它,Cool的成分可能占得更多。装饰重要作用就是简洁代码、提高代码的复用,能灵活用起来确实能解决一些问题,可惜的是,其合适的场景还有待开发,目前来看多是用于网站后端登录验证、日志的记录、缓存的刷新、以及输入数据的合理性检查上,这些场景的特点看起来就是高度重复并且重要(我想了一下,我目前还接触不到)。所以,装饰器在我手里就是把“牛刀”吧。
四、以关于“代码复用”的思考作为结尾吧
这次重学装饰器,一方面是确实被这种缓存刷新方法惊艳到,想要进一步了解一下,另一方面也是想积累一些提高代码复用能力的方法,装饰重要作用就是简洁代码、提高代码的复用能力,对于高度重复并且重要的部分可以考虑用装饰器来进行优化。
最后,代码的复用性强确实能带来很多开发上的便捷,但是也不需要时刻紧绷神经,时刻在编码的时候拧着自己的大腿,边念叨着“这以后的复用啊”边进行编程,这看起来像是一种变相的内耗和负担了。
在有关代码重构的“三次法则(Rule of Three)”规则中指出,“允许按需直接复制粘贴代码一次,但如果相同的代码片段重复出现三次以上的时候,需要将其提取出来做成一个子程序”[②],也就是说,一段代码被重复地复制、粘贴(三次以上,两次都不值得),那么是时候考虑将它抽取出来做成单独的模块了,或许,厉害的工程师能够预判到这种重复功能,并提前做好单独模块的开发预算,从而节省接下来重构的时间。如果要问他们具体是怎么做到的?
这个时候通常会伴有工程师的微微一笑,并说道:“无他,唯手熟尔”
参考链接:
[①] https://www.runoob.com/w3cnote/python-func-decorators.html
[②] https://zh.wikipedia.org/wiki/三次法则_(程序设计)