“这就是你的变量命名啊?“
这是我作为一个半路出家的数据分析师,第一次跟组里最资深的程序猿交流的时候,得到的点评。
当我们还是一个Python新手的时候,通常一次性只写十几行、几十行代码,这时候命名规范的重要性还不能体现出来。因为我们的程序变量数量不多,容易区分,而且程序的逻辑也比较简单。
但是当我们写的代码逐渐多起来、程序逐渐大起来以后,命名遵循一定的范式就显得非常重要了。如果在大型的项目中,命名不规范,不仅使得程序的可读性大大下降,同时也使得我们很难从变量名中知道这个变量是干什么的。
可以这么说,其他程序员看到你的变量命名,就好像其他篮球爱好者看到你的投篮姿势、其他钢琴爱好者看到你的手型、其他厨师看到你切的菜一样,是判断你是否professional的重要方法。
本文就来详细解读一下,Python中的变量命名习惯。
一、Python的惯用命名方法
常用的命名方法包括驼峰命名法(Camel Case)、匈牙利命名法(Hungarian Notation)、帕斯卡命名法(Pascal)、下划线命名法(Snake Case)。
根据Python之父、荷兰程序猿Guido van Rossum的建议,Python中变量的命名应当以Snake Case为主。具体命名方式大致分为以下三种。
(一)绝大多熟情况下建议使用Snake Case命名,即全部字母均小写,用下划线代替单词间的空格
具体包括:
1.模块名
public:module_name
internal:_module_name
例如,我们可以把一个模块的文件命名为my_module.py。
这里要注意,虽然有一些比较老的模块仍然用的是MyModule这种命名方法,但是现在已经不推荐这样命名了。因为,当一个模块和一个类同名的时候,我们就搞不清楚到底指的是类还是模块了。
例如,我可能会搞混,到底写的是
import StringIO
还是
from StringIO import StringIO
2.包名
Public:package_name
3.方法名
Public:method_name()
Internal:_method_name()(被保护的)
4.函数名
Public:function_name()
Internal: _function_name()
5.全局变量名/类的变量名
Public:global_var_name
Internal: _global_var_name
6.实例对象名
Public:instance_var_name
Internal: _instance_var_name(被保护的)
7.函数的参数名
Public:function_parameter_name
8.局部变量名
Public:local_var_name
(二)少部分情况下,建议使用大驼峰命名
具体包括:
1.类名
Public:ClassName
Internal: _ClassName
2.报错名
Public:ExceptionName
(三)只有一种情况下,全部字母都大写
那就是:
1.全局常量名/类的常量名
GLOBAL_CONSTANT_NAME
Internal: _GLOBAL_CONSTANT_NAME
二、应当避免的变量命名
(一)避免由单独一个字母组成的变量名
很多初学者,甚至有一些水平比较低的老师,都喜欢用a、b、c这种单个字母来给变量命名,这是不可取的。
因为这种变量名里面不包含任何信息,变量稍微多一点,程序稍微长一点,很容易就搞不清楚谁是谁、每个变量是干什么的了。
但是,要除开几个特殊的、约定俗成的情况:
1.计数器或者迭代器(例如,i、j、k、v等)
例如,
for i in range(100):
print(i)
2.字母e在作为 try/except 语句中的异常标识符的时候。
例如,下面的代码可以准确的定位错误类型与错误明细:
a = [1,2,3]
try:
a[3]
except Exception as e: # 注意e在这里的用法
print('错误类型是',e.__class__.__name__)
print('错误明细是',e)
3.字母f在with语句中作为文件句柄的时候
例如,如果我们要读取一个文件:
with open('/path/to/file', 'r') as f:
print(f.read())
for line in f.readlines():
print(line.strip()) # 把末尾的'\n'删掉
现在我们知道了,用单个字母做变量名肯定是不行的。那一个变量的名字要取得多详细才合适呢?
通常来说,一个变量名的详细程度应当与这个变量在程序中出现的范围成正比。
例如,如果我们整个程序总共就不到10行代码,那么,我们用i来给一个变量命名是完全OK的。而且,此时通常就用一个单词做一个变量名。如果在这么短的程序中,每个变量都像this_is_a_variable_name一样,这么长,反而会显得很不协调、很奇怪。
如果我们的程序存在比较复杂的嵌套关系,而且一个变量在总共大几百行代码中的多个位置均有出现,那么我们就不能用i来给一个变量命名了,这是我们就要让这个变量的名字包含足够多的信息,我们才能有效地知道,它是谁,从哪儿来,到哪儿去,要干什么。
(二)避免在任何包名或者模块名中使用中划线(-)。
(三)避免在一个变量的开头和结尾加双下划线
例如:this_name。
因为这种类型的变量名是由Python所保留的,用户不能自己定义这种变量名。
(四)不要存在冒犯性的词汇
否则会引起阅读代码的人的不适。如果是开源的代码,那么在代码传播的时候,会存在不好的影响。如果你是为商业公司写代码,那么你有可能影响你的前途,或者商业公司的声誉。
(五)不必要地把变量类型加入到变量名中
例如,id_to_name_dict,就是不合适的命名方法。
我们要知道,Python是动态类型语言。
三、文件名中的下划线
(一)
Internal意味着在一个模块的内部,或者是在类中被保护的或者是私有的。
(二)
在变量名前加单个下划线 (_) 可以保护模块中的变量和函数,因为linters会标记受保护的成员权限。
这个符号达到的效果是,只有类对象和子类对象自己能访问到这些变量,且不能用’from module import’导入函数。
(三)
在实例变量或方法前添加双下划线(即__,又名“dunder”),可以有效地使变量或方法成为它所属的类的私有变量或者私有方法(通过使用name mangling)。
它的效果是只有类对象自己能访问,连子类对象也不能访问到这个数据。
但是,我们不鼓励在变量或者方法前加双下划线,因为它会影响可读性和可测试性,而且并不能做到真正私有。
(四)
下划线也可能出现在以test开头的unittest method的名称中,用以分隔这个名称中的各个逻辑组件,即使这些组件本身使用了类似于CapWords的命名方法。
例如,test_就是一个可行的命名样式。
例如,testPop_EmptyStack就是根据上面的样式,命名出的一个可接受的名称。它以test开头,Pop和EmptyStack是两个逻辑组件,他们本身都是CapWorks式的命名方法,但是两个组件之间仍然用_分隔开。
我们要注意,命名test methods是没有唯一的正确方法的。
四、其他注意事项
(一)谨慎地使用缩写
此外,我们还要注意,函数名(function name)、变量名、文件名应当是描述性的,要尽量避免缩写。
不过,少数几个常见的、公认的缩写,我们是可以直接使用的:
- temp–>tmp
- flag–>flg
- statistic–>stat
- increment–>inc
- message–>msg
特别地,不要使用有歧义的缩写或者是你的项目以外的人不熟悉的缩写,同时也不要简单地通过删除一个单词中的字母来创造缩写。
有歧义,一般就指的是一种缩写可能对应多个单词。
另外我还见过一种奇葩的歧义,在这里分享一下,供大家一笑。
我一个学长在做teaching fellow的时候,曾经收到学生交的作业,这个学生在给作业文件命名的时候,把assignment简写成ass。因此,ta的作业下载下来全是,xxx_ass1.py、xxx_ass2.pdf、xxx_ass3.jpg,其中xxx是一个人名(逃
所以,这也是我们要谨慎使用缩写的原因。
(二)
我们应将所有相关的类和最高层级函数放在一个模块中。这一点和Java不一样,Python程序的一个模块中可以有多个类,而不是一个模块中仅能有一个类。
(三)
对于包含大量数学计算的代码,我们通常倾向于使用一些较短的、在参考文献或算法中已经建立、并惯用的符号表示来命名,尽管这些变量名通常会违本文的Python样式指南。
在定义这些变量名的时候,我们要在注释或文档字符串(docstring)中引用所有命名约定的来源。
如果命名约定的来源不可访问了,那么我们要清晰地记录下命名约定的内容具体是什么。
(四)
对于公共的API,我们更倾向于使用符合PEP8的descriptive_names,在脱离代码的上下文语境的时候,这个更有用。
(五)
在创建python脚本的时候,我们要永远使用.py作为文件名扩展。
永远不要在文件名中使用中划线(-)。
如果我们想要在没有文件扩展名的情况下去访问可执行文件,那么需要使用symbolic link或包含 exec “ [ 0. p y ] ( h t t p s : / / l i n k . z h i h u . c o m / ? t a r g e t = h t t p [0.py](https://link.zhihu.com/?target=http%3A//0.py/)" " [0.py](https://link.zhihu.com/?target=http@” 的简单bash包装器。
最后我自己整理了一些学习资料,希望对你们有帮助。
点此免费领取:优快云大礼包:《python学习路线&全套学习资料》免费分享
Python学习大纲
Python所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。
入门学习视频
Python实战案例
光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。
最后,千万别辜负自己当时开始的一腔热血,一起变强大变优秀。