乐趣区

关于linux:Python-工匠善用变量来改善代码质量

一、『Python 工匠』是什么?

我始终感觉编程某种意义上是一门『手艺』,因为优雅而高效的代码,就如同完满的手工艺品一样让人赏心悦目。

在雕刻代码的过程中,有大工程:比方应该用什么架构、哪种设计模式。也有更多的小细节,比方何时应用异样(Exceptions)、或怎么给变量起名。那些真正优良的代码,正是由有数优良的细节造就的。

『Python 工匠』这个系列文章,是我的一次小小尝试。它专一于分享 Python 编程中的一些偏『小』的货色。心愿可能帮到每一位编程路上的匠人。

二、变量和代码品质

作为『Python 工匠』系列文章的第一篇,我想先谈谈『变量(Variables)』。因为如何定义和应用变量,始终都是学习任何一门编程语言最先要把握的技能之一。

变量用的好或不好,和代码品质有着十分重要的分割。在对于变量的诸多问题中,为变量起一个好名字尤其重要。

三、如何为变量起名

在计算机科学畛域,有一句驰名的格言(俏皮话):

There are only two hard things in Computer Science: cache invalidation and naming things.
在计算机科学畛域只有两件难事:缓存过期 和 给货色起名字
– Phil Karlton

第一个『缓存过期问题』的难度不必多说,任何用过缓存的人都会懂。至于第二个『给货色起名字』这事的难度,我也是深有体会。在我的职业生涯里,度过的作为光明的下午之一,就是坐在显示器前抓耳挠腮为一个新我的项目起一个适合的名字。

编程时起的最多的名字,还数各种变量。给变量起一个好名字很重要,因为好的变量命名能够极大进步代码的整体可读性。

上面几点,是我总结的为变量起名时,最好恪守的根本准则。

1. 变量名要有描述性,不能太宽泛

可承受的长度范畴内,变量名能把它所指向的内容形容的越准确越好。所以,尽量不要用那些过于宽泛的词来作为你的变量名:

  • BAD: day, host, cards, temp
  • GOOD: day_of_week, hosts_to_reboot, expired_cards

2. 变量名最好让人能猜出类型

所有学习 Python 的人都晓得,Python 是一门动静类型语言,它(至多在 PEP 484 呈现前)没有变量类型申明。所以当你看到一个变量时,除了通过上下文猜想,没法轻易晓得它是什么类型。

不过,人们对于变量名和变量类型的关系,通常会有一些直觉上的约定,我把它们总结在了上面。

『什么样的名字会被当成 bool 类型?』
布尔类型变量的最大特点是:它只存在两个可能的值『』或『 不是 』。所以,用 is、has 等非黑即白的词润饰的变量名,会是个不错的抉择。准则就是: 让读到变量名的人感觉这个变量只会有『是』或『不是』两种值。

上面是几个不错的示例:

  • is_superuser:『是否超级用户』,只会有两种值:是 / 不是
  • has_error:『有没有谬误』,只会有两种值:有 / 没有
  • allow_vip:『是否容许 VIP』,只会有两种值:容许 / 不容许
  • use_msgpack:『是否应用 msgpack』,只会有两种值:应用 / 不应用
  • debug:『是否开启调试模式』,被当做 bool 次要是因为约定俗成

『什么样的名字会被当成 int/float 类型?』
人们看到和数字相干的名字,都会默认他们是 int/float 类型,上面这些是比拟常见的:

释义为数字的所有单词,比方:port(端口号)、age(年龄)、radius(半径) 等等

应用 _id 结尾的单词,比方:user_id、host_id

应用 length/count 结尾或者结尾的单词,比方: length_of_username、max_length、users_count

留神:不要应用一般的复数来示意一个 int 类型变量,比方 apples、trips,最好用 number_of_apples、trips_count 来代替。

其余类型

对于 str、list、tuple、dict 这些简单类型,很难有一个对立的规定让咱们能够通过名字去猜想变量类型。比方 headers,既可能是一个头信息列表,也可能是蕴含头信息的 dict。

对于这些类型的变量名,最举荐的形式,就是编写标准的文档,在函数和办法的 document string 中,应用 sphinx 格局(Python 官网文档应用的文档工具)来标注所有变量的类型。

3. 适当应用『匈牙利命名法』

第一次晓得『匈牙利命名法』,是在 Joel on Software 的一篇博文中。简而言之,匈牙利命名法就是把变量的『类型』缩写,放到变量名的最后面。

关键在于,这里说的变量『类型』,并非指传统意义上的 int/str/list 这种类型,而是指那些和你的代码业务逻辑相干的类型。

比方,在你的代码中有两个变量:students 和 teachers,他们指向的内容都是一个蕴含 Person 对象的 list。应用『匈牙利命名法』后,能够把这两个名字改写成这样:

students -> pl_students
teachers -> pl_teachers

其中 pl 是 person list 的首字母缩写。当变量名被加上前缀后,如果你看到以 pl_ 打头的变量,就能晓得它所指向的值类型了。

很多状况下,应用『匈牙利命名法』是个不错的主见,因为它能够改善你的代码可读性,尤其在那些变量泛滥、同一类型屡次呈现时。留神不要滥用就好。

4. 变量名尽量短,然而相对不要太短

在后面,咱们提到要让变量名有描述性。如果不给这条准则加上任何限度,那么你很有可能写出这种描述性极强的变量名:how_much_points_need_for_level2。如果代码中充斥着这种过长的变量名,对于代码可读性来说是个劫难。

一个好的变量名,长度应该管制在 两到三个单词左右。比方下面的名字,能够缩写为 points_level2

绝大多数状况下,都应该防止应用那些只有一两个字母的短名字,比方数组索引三剑客 i、j、k,用有明确含意的名字,比方 persion_index 来代替它们总是会更好一些。

应用短名字的例外情况

有时,下面的准则也存在一些例外。当一些意义明确然而较长的变量名反复呈现时,为了让代码更简洁,应用短名字缩写是齐全能够的。然而为了升高了解老本,同一段代码内最好不要应用太多这种短名字。

比方在 Python 中导入模块时,就会常常用到短名字作为别名,像 Django i18n 翻译时罕用的 gettext 办法通常会被缩写成 _ 来应用(from django.utils.translation import ugettext as _)

5. 其余注意事项

其余一些给变量命名的注意事项:

  • 同一段代码内不要应用过于类似的变量名,比方同时呈现 users、users1、user3 这种序列
  • 不要应用带否定含意的变量名,用 is_special 代替 is_not_normal

四、更好的应用变量

后面讲了如何为变量取一个好名字,上面咱们谈谈在日常应用变量时,应该留神的一些小细节。

1. 放弃一致性

如果你在一个办法内外面把图片变量叫做 photo,在其余的中央就不要把它改成 image,这样只会让代码的阅读者困惑:『image 和 photo 到底是不是同一个货色?』

另外,尽管 Python 是动静类型语言,但那也不意味着你能够用同一个变量名一会示意 str 类型,过会又换成 list。同一个变量名指代的变量类型,也须要放弃一致性。

2. 尽量不要用 globals()/locals()

兴许你第一次发现 globals()/locals() 这对内建函数时很兴奋,急不可待的写下上面这种极其『简洁』的代码:

万不要这么做,这样只会让读到这段代码的人(包含三个月后的你本人)痛恨你,因为他须要记住这个函数内定义的所有变量(想想这个函数增长到两百行会怎么样?),更别提 locals() 还会把一些不必要的变量传递进来。

更何况,The Zen of Python(Python 之禅)说的清清楚楚:Explicit is better than implicit.(显式优于隐式)。所以,还是老老实实把代码写成这样吧:

3. 变量定义尽量凑近应用

这个准则属于陈词滥调了。很多人(包含我)在刚开始学习编程时,会有一个习惯。就是把所有的变量定义写在一起,放在函数或办法的最后面。

这样做只会让你的代码『看上去很整洁』,然而对进步代码可读性没有任何帮忙。

更好的做法是,让变量定义尽量凑近应用。那样当你浏览代码时,能够更好的了解代码的逻辑,而不是吃力的去想这个变量到底是什么、哪里定义的?

4. 正当应用 namedtuple/dict 来让函数返回多个值

Python 的函数能够返回多个值:

然而,这样的用法会产生一个小问题:如果某一天,latlon_to_address 函数须要返回『城区(District)』时怎么办?

如果是下面这种写法,你须要找到所有调用 latlon_to_address 的中央,补上多进去的这个变量,否则 ValueError: too many values to unpack 就会找上你:

对于这种可能变动的多返回值函数,应用 namedtuple/dict 会更不便一些。当你新增返回值时,不会对之前的函数调用产生任何破坏性的影响:

不过这样做也有害处,因为代码对变更的兼容性尽管变好了,然而你不能持续用之前 x, y = f() 的形式一次解包定义多个变量了。取舍在于你本人。

5. 管制单个函数内的变量数量

人脑的能力是无限的,钻研表明,人类的短期记忆只能同时记住不超过十个名字。所以,当你的某个函数过长(一般来说,超过一屏的的函数就会被认为有点过长了),蕴含了太多变量时。请及时把它拆分为多个小函数吧。

6. 及时删掉那些没用的变量

这条准则非常简单,也很容易做到。然而如果没有恪守,那它对你的代码品质的打击是覆灭级的。会让浏览你代码的人有一种被愚弄的感觉。

所以,请关上 IDE 的智能提醒,及时清理掉那些定义了然而没有应用的变量吧。

7. 能不定义变量就不定义

有时候,咱们定义变量时的心理流动是这样的:『嗯,这个值将来说不定会批改 / 二次应用』,让咱们先把它定义成变量吧!

没有必要为了那些可能呈现的变动,就义代码以后的可读性。如果当前有定义变量的需要,那就当前再加吧。

五、结语

碎碎念了一大堆,不晓得有多少人可能保持到最初。变量作为程序语言的重要组成部分,值得咱们在定义和应用它时,多花一丁点工夫思考一下,那样会让你的代码变得更优良。

这是『Python 工匠』系列文章的第一篇,不晓得看完文章的你,有没有什么想吐槽的?请留言通知我吧。

腾讯蓝鲸智云(简称蓝鲸)软件体系是一套基于 PaaS 的技术解决方案,致力于打造行业当先的一站式自动化运维平台。目前曾经推出社区版、企业版、私有云版,欢送体验。

官网:https://bk.tencent.com/

下载链接:https://bk.tencent.com/download/

退出移动版