一文搞定代码中的命名

导语

Phil Karlton 曾经说过:计算机科学领域只有两件难事:缓存失效和命名。而命名又是写出整洁代码基础中的基础,本文的副标题其实是《关于命名的读书笔记》,自己在学习过程中的整理出来一点心得笔记,共勉!

为什么要做好命名?

任何一个傻瓜都能写出计算机可以理解的代码。唯有写出人类容易理解的代码,才是优秀的程序员。—— Martin Fowler

整洁的代码如同优美的散文。—— Grady Booch

程序写出来是给人看的,附带能在机器上运行。–《计算机程序的结构与解释》

读悬疑侦探类小说,透过神秘的文字推测故事情节是个挺不错的体验。但是如果是在阅读代码,这种体验会让你泪奔。

做好命名很难

起名字这件事看似不难,但是要经过深思熟虑,取出名副其实、表达性好的名字并不是一件很容易的事。

命名为什么难呢?因为命名的过程本身就是一个抽象和思考的过程,在工作中,当我们不能给一个模块、一个对象、一个函数,甚至一个变量找到合适的名称的时候,往往说明我们对问题的理解还不够透彻,需要重新去挖掘问题的本质,对问题域进行重新分析和抽象,有时还要调整设计和重构代码。因此,好的命名是我们写出好代码的基础。

就像 Stack Overflow的创始人 Joel Spolsky所说的:”起一个好名字应该很难,因为一个好名字需要把要义浓缩在一到两个词中。(Creating good names is hard, but it should be hard,because a great name captures essential meaning in just one or two words.)”

此外, Martin Fowler也表示过,他最喜欢的一句谚语,就是我们的导语中提到的那句话:”在计算机科学中有两件难事:缓存失效和命名。(There are only two hard things in Computer Science:cache invalidation and naming things.)”

变量命名

1)好的命名的注意事项

1.1)命名要名副其实

这是为变量命名时最重要的考虑选项。名字要完全、准确的描述出该变量代表的事物。

最简单的方法是用文字描述变量所表达的含义,对变量的描述就是最好的变量名。这种名字很容易阅读,因为它不包含容易晦涩的缩写,同时也没有歧义。因为他对代表的事物做了完整描述,因此不容易混淆。

如描述运动场中座椅数数量, number_of_sets_in_the_stadium

备注: 本文命名都以 python的命名方式书写,其他语言的根据语言命名格式转换即可。

如果有一种变量你没法描述,那么说明你可能要重新思考业务,思考逻辑。

1.2)以问题为导向

好记的名字往往反映的通常都是问题,而不是解决方案。好的名字通常表达 what ,而不是 how ,如果名字反映了计算的某些方面而不是问题本身,那么它反映的就是 how 而不是 what

举例子说明一个员工的数据记录, input_rec 或者 employee_datainput_rec 反映的就是输入记录这些计算机学术用语。 employee_data 则直指问题。那么 employee_data 就是个好名字。

1.3)最佳的命名长度

变量名的最佳长度似乎应该介于 nnumber_of_sets_in_the_stadium 之间。太短的名字无法传达足够的信息。太长的名字很难写,同时还会使程序视觉结构变得模糊不清。

国外的大佬 Gorla、Benander 研究发现,当变量名平均在 10 到 16 个字符的时候,调试程序所花费的时间最小,平均名字长度在 8 到 20 个字符的时候也很适合调试。这项原则并不是要求你一定要把变量控制在 8 到 16 的长度。它强调的是如果你查看自己写的代码时发现很多更短的名字,你需要好好斟酌,确保这些名字是否足够清晰表达其含义。

太长: number_of_sets_in_the_stadium

太短: n,nsisd

正好: num_sets_in_stadium
1.4)变量名中的限定词

很多程序都有表示计算结果的变量:总额、平均值、最大值等等,如果要用类似 total、sum、average、max、min、record、string、pointer这样的限定词来修饰某个事物,请把限定词放到名字的最后。

因为变量名中最重要的,即为这一变量赋予主要含义的部分应当位于最前面,这样这一部分就可以显得最为突出,又可以首先被阅读到。另外将限定词统一放在后面可以提高可读性,简化维护工作。

2)为特定类型的数据命名

2.1)为循环下标命名

循环我们基本上天天用,小到写个 shell 脚本,大到登月工程,在软件工程中很常见。

既然经常那么 i、j、k 这些想来你也不陌生。如果一个变量要在循环之外用,那么就应该为它取一个比 i、j 或者 k 更有意义的名字。

如果循环不是简单几行,阅读代码的人很容易就忘记本来的含义。

fruits = ['banana','apple','mango']
for fruit in fruits:
   print(f"当前水果:{fruit}")

为循环下标变量命名可以避免下标串话,就是想写j的时候写了i,笔者本人之前写循环的时候就串话了,导致那个bug上了调试才定位找出来。

当然 i、j、k这三个循环下标从c语言开始就伴随着我们,深入人心,所以想要用的时候尽量避免用于非下标情况,给人造成误解(想个更具有描述性的名字这事不就解决了)。

2.2)为状态变量命名

状态变量主要为了描述你的程序的状态。

建议把标记也看作状态变量的一种,起一个比 flag 、status 更好的名字,标记的名字不应该包含 flag ,因为你看不出该标记是做什么的。为了清楚起见我们还应该用枚举类型、具名常量或者用作居民常量的全局变量来进行赋值。

2.3)为临时变量命名

临时变量用于存储计算的中间结果。

我们经常把它们写成 temp、x或者其他一些模糊且缺乏描述性的名字(有没有躺枪…)。

临时变量是一个信号,表明你还没有完全把问题理解清楚。而且,因为我们将这些变量”正式”的赋予了一种”临时”状态,我们就会往往更加随意的对待它,当你忽略它,那么就有出错的可能了。

临时性的保留一些值常常是有必要的,但是确实不管从哪个角度看,你程序中的大多数变量都是临时的,把其中个别的称为临时性,说明你还没有弄清楚它们的实际用途。

2.4)为布尔变量命名
  • 推荐一些经典的布尔变量名
  • done:
    用来表示某件事已经完成。完成前 False ,完成后为 True 。
    error:
    用来表示有错误发生。错误发生前 False ,发生时设置为 True 。
    found:
    用来表示某个值已经找到。没找到前 False ,找到后为 True 。
    success 或者 ok:
    用来表示某项操作是否成功。操作失败 False ,操作成功为 True 。
  • 给布尔变量赋予隐含”真假”含义的名字
  • donefound就是不错的布尔变量名,因为其状态要么是 True ,要么是 False ,但是像 status 确实很糟糕的布尔变量值,因为它没有明确的 TrueFalsestatusTrue表示啥?
  • 还有程序员喜欢在他们写的布尔变量名前加上 is(有没有躺枪-_-|)。加上了 is后,变量名就变成了 is_error?is_complete?优点之一就是不会用于不隐含”真假含义”的名字了,如 is_status,缺点就是降低可读性,比如 if(is_found)可读性略差于 if(found)
  • 使用肯定的布尔变量名
  • 比如not_found,not_done这样看起来就比较难读了,来个语句你感受一下。
    if not not_found
    玩门萨测试呢?这样的名字就应该替换为 found 之类的。
2.5)为具名常量命名

因为具名常量很像变量,所以放在这里说一下。在为具名变量命名的时候,应该依据常量代表的含义命名,而不是该常量所代表的数值。

3)应该避免的名字

避免使用令人误解的名字或者缩写

要确保名字的含义是正确的,大家知道 ATM 机是取钱的,但是网络中有 Asynchronous Transfer Mode(ATM)异步传输模式,这种容易引起误解的尽量避免。

3.1)避免使用具有相似含义的名字

如果两个变量的名字交换而不影响你对程序的理解,那么你就需要为这两个变量重新改名字了,因为如果用在同一段代码里面很容易混淆,出现一下子不好发现的错误。

避免使用具有不同含义但却有相似名字的变量

如果含义不同却名字相似的也要避免,比如 client_recsclient_reps。这样的名字只差一个字母,再加上编辑器补全时候很容易忽视,导致出现错误。

3.2)避免使用发音相近的名字

使用发音相近的词作为变量,主要有两个不合适点:

  • 第一个就是跟人讨论时候,容易误解。
  • 第二做语音类测试时候。
3.3)避免在名字中使用数字

如果名字中的数字真的很重要,建议使用数组代替一组单个的变量。如果数组不合适,那么数字就更不合适了。要避免 file1file2total1total2 这种变量,过一段时间谁也不知道它们是啥,你总可以想出不加数字就能区分变量的名字吧。特殊情况要特殊对待,比如深圳去上海的 G205 国道,美国的 51 区,建议再创建一个含有数字名字之前,请确定没有更好的选项。

3.4)避免在名字中拼错单词

本来别人看你代码就要花点脑细胞,结果你拼错了。
content 和 context
highlite 和 hilite
大哥们,饶了看你代码的人吧。

3.5)避免仅靠大小写来区分变量名

所以语言区分大小写,但还是避免仅靠大小写区分变量,大写名字和小写名字字面意思一样,还是不要做不同的变量了吧。

3.6)避免使用标准类型,变量和函数的名字

不要用语言的关键字。很多语言现在不能写关键字,但是大小写不区分,比如python代码:

>>> if = 1
  File "", line 1
    if = 1
       ^
SyntaxError: invalid syntax
>>> If = 1
>>>

本文提供了这么多变量名的方法就不要用关键字这种了。

3.7)避免使用与变量含义完全无关的名字

一文搞定代码中的命名

就问你怕不怕?还有的喜欢给变量起一些对自己特殊意义的名字作为变量名,除非程序真的跟你特殊意义有关。这些能避免避免吧。

3.8)避免在名字中包含容易混淆的字符

把下列不属于该组的名字圈出来:

eye_Chart1 ttl5 TTLCONFUSION

eye_ChartI ttlS TTLCONFUSION

eye_Chart1 tt1S TTLC0NFUSION

还是不要搞这些找不同游戏才能出现的变量哈。

函数命名

1. 描述函数所做的所有事情

函数的命名应该是动词或者动词短语,如 delete_pagesave等。

函数的名字应该描述其所有的输出结果以及副作用,比如你的函数是计算报表总额并打开一个输出文件,那么把它命名为 computer_report_totals() 不能算完整。完整的应该是 computer_report_totals_and_open_output_file()

如果写一些带有副作用的子程序,那么就会起出上面那种长出天际的名字,解决这个问题的办法不是使用描述性较弱的 computer_report_totals() 命名方式,而是换一种编写方式,直接了当地写成解决问题,不产生副作用。

2. 给函数命名时要对返回值有所描述

函数有返回值,因此,函数的命名要应该针对其返回值进行。比如说 xxx_is_ready 这样的,一看就让人知道是返回的布尔值。

3. 准确使用对仗词

命名时遵守对仗词的命名规则有助于保持一致性,从而提高可读性。像 first/last,这样的对仗词就很容易理解,而像 file_open()l_close() 就很让人迷惑了,下面列出一些常见的对仗词组。

add/remove
increment/decrement
open/close
begin/end
insert/delete
show/hide
create/destroy
lock/unlock
source/target
first/last
min/max
start/stop
get/put
next/previous
up/down
get/set
old/new
4. 函数名字长度

研究表明,变量名的最佳长度是9到15个字符,在面向对象的语言中,函数是跟在对象的名字之后,这实际上是为其提供了一部分的名字。重点的尽可能的含义清晰,长短要视名字是否清晰而定。

5. 为常用操作确立命名规则

在某些系统里,区分不同类别非常重要,而命名规则往往能是指示这种区别的最简单也是最可靠的办法。忽视了为返回对象标识的类函数建立一个命名规则,看看下面的名字

  • employee.id.get()
    dependent.get_id()
    candidate.get_id()
6. 类命名

类的命名应该是名词或者名词短语,如 Customer 或者 AddressParser

命名工具推荐

Codelf 由前网易前端工程师知名移动前端调试工具 MIHTool 的作者基于 searchcode 和有道词典开发完成。目前开源在 Github上。

Codelf:http://unbug.github.io/codelf/
Codelf 的 github repo:https://github.com/unbug/codelf

文学系的可以搜搜热词: 盘它

一文搞定代码中的命名

我太南了

一文搞定代码中的命名

总结

白居易每作一首诗,都要给不识字的老太太念念,老太太能听懂的,就要,听不大懂的,就改。我们的代码命名是我们写成好代码的基础,也应该奔着这个目标走。大家看文章过程中觉得有不妥的或者不合适的地方,欢迎讨论交流哈。

参考书籍

《代码大全2》:https://book.douban.com/subject/1477390/
《代码整洁之道》:https://book.douban.com/subject/4199741/
《重构》:https://book.douban.com/subject/30468597/

转自:于颜川KM分享

更多后台和前端开发规范

蓝鲸文档中心开发指南:https://bk.tencent.com/docs/document/6.0/130/5871

Python代码规范小结:https://bk.tencent.com/s-mart/community/question/1078

蓝鲸智云

本文由腾讯蓝鲸智云编辑发布,腾讯蓝鲸智云(简称蓝鲸)软件体系是一套基于PaaS的技术解决方案,致力于打造行业领先的一站式自动化运维平台。目前已经推出社区版、企业版,欢迎体验。

Original: https://www.cnblogs.com/tencent-blueking/p/16434728.html
Author: 腾讯蓝鲸智云
Title: 一文搞定代码中的命名

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/596394/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • MySQL数据库如何线上修改表结构

    一、MDL元数据锁 在修改表结构之前,先来看下可能存在的问题。 1、什么是MDL锁 MySQL有一个把锁,叫做MDL元数据锁,当对表修改的时候,会自动给表加上这把锁,也就是不需要自…

    Python 2023年10月23日
    038
  • TensorFlow2安装教程

    1.安装Anaconda3 清华镜像源: Index of /anaconda/archive/ | 清华大学开源软件镜像站 | Tsinghua Open Source Mirr…

    Python 2023年9月30日
    0168
  • 《痞子衡嵌入式半月刊》 第 68 期

    痞子衡嵌入式半月刊: 第 68 期 这里分享嵌入式领域有用有趣的项目/工具以及一些热点新闻,农历年分二十四节气,希望在每个交节之日准时发布一期。 本期刊是开源项目(GitHub: …

    Python 2023年10月12日
    043
  • Python pandas使用map, apply和applymap实现对DataFrame进行单列/行,多列/行,以及所有元素的操作

    最近在查看网上关于pandas DataFrame使用map, apply和applymap的说明时,发现许多博文未能写清楚关键点。这里整理一下每个函数的使用范围和适用情况。 首先…

    Python 2023年8月6日
    039
  • Anaconda与Jupyter Notebook入门级详细使用教程

    Anaconda 简介 我们用Anaconda发行版作为Python的使用环境。Anaconda指的是一个开源的Python发行版本,其包含了conda、Python等180多个科…

    Python 2023年8月1日
    036
  • pandas 处理excel表格数据的常用方法(python)

    最近助教改作业导出的成绩表格跟老师给的名单顺序不一致,脑壳一亮就用pandas写了个脚本自动吧原始导出的成绩誊写到老师给的名单中了哈哈哈,这里就记录下用到的pandas处理exce…

    Python 2023年8月2日
    056
  • 基于深度神经网络的中药材识别

    摘 要 近年来,受到我国国民经济发展与社会财富积累增速加快的影响,人们对自己的身体健康也越来越重视,很多的人都选择在服用中草药来治疗疾病、改善体质,因此,我国的中药材行业在这一段时…

    Python 2023年9月29日
    044
  • 浅拷贝与深拷贝

    在JavaScript中存在两大数据类型:基本类型、引用类型。 基本数据类型存放在栈中,是一段简单的数据段, 数据大小确定,内存空间大小可以分配,是直接按值存放的,可以 按值访问。…

    Python 2023年10月14日
    035
  • Django 路由配置 (二)

    django处理请求 Django 和其他 Web 框架的 Http 处理的流程大致相同,web服务器软件或者模块(wsgiref)会把http 发送的请求封装成了一个 Reque…

    Python 2023年8月6日
    057
  • 算法 | 详解斐波那契数列问题

    本篇是学习了《趣学算法(第2版)》 第一章之后总结的。 上一篇讲到了等比数列求和问题,求(S_n = 1 + 2 + 2^2 + 2^3 + … + 2^{63}= ?…

    Python 2023年10月18日
    034
  • 读书方法

    旧书不厌百回读,熟读深知子自知。 要研究透彻本专业的经典。 读书要学会终身下苦功夫,知十而非真知,不如知一之真知也,读书不能一知半解。 读书决定了一个人的见识和思想的深刻,这些都是…

    Python 2023年10月25日
    033
  • NLP实战:面向中文电子病历的命名实体识别

    一.前言 本篇文章是关于NLP中的中文命名实体识别(Named Entity Recognition,NER)的实战项目,该项目利用了大型预训练语言模型BERT和BiLSTM神经网…

    Python 2023年9月29日
    044
  • concat, join, 和merge的区别在Python中

    concat: Pandas函数 可以垂直和水平地连接两个或多个pandas对象 只用索引对齐 索引出现重复值时会报错 默认是外连接(也可以设为内连接) join: DataFra…

    Python 2023年8月21日
    054
  • Python 获取图片某像素BGR值并生成纯色图 | Python工具

    前言 最近,需要获得特定图片的像素颜色并生成该颜色的纯色图片。所以我写了一个工具,并与你分享。如果你有相同的场景,你可以直接使用它。 [En] Recently, there is…

    Python 2023年5月24日
    089
  • 微服务架构 | 4. 服务调用

    参考资料:《Spring Microservices in Action》《Spring Cloud Alibaba 微服务原理与实战》《B站 尚硅谷 SpringCloud 框架…

    Python 2023年6月3日
    081
  • mapreduce统计单词个数

    WordCount类代码: import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.Pat…

    Python 2023年6月16日
    057
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球