常见的命名规则
- 匈牙利命名法:
- 以一至多个小写字母表示其属性、类型,后接首字母大写的一至多个单词表示其作用描述。
- 比如
m_bCanRun
,其中m_
表示其为成员变量,b
表示其类型为布尔值,CanRun
表示其代表是否可以检查的含义。
- 驼峰命名法:
- 以一至多个逻辑单元构成,每个逻辑单元可称为一个识别字,
- 首个识别字首字母小写,其余识别字首字母大写,比如
canRun
, - 由于首字母小写,这种形式也被称为小驼峰命名法。
- 帕斯卡命名法:和驼峰命名法类似,区别为首字母大写,如
CanRun
,也被称为大驼峰命名法。 - 下划线命名法:和驼峰命名法类似,区别为所有识别字均小写,识别字之间使用
_
连接,比如can_run
。
Python 常用的命名方式
通用准则:
- 无论你编写的模块、类、还是函数,其中对外暴露出的公共使用部分的命名应从使用场景出发。比如
os
模块中makedirs
、removedirs
等函数的命名,我们可以清楚的知道这些函数的使用场景,而不用关心其内部实现; - 尽量使用完整的、准确的、易于理解的、具有明确目的的单词来命名,或者使用下划线将可以表达完整含义的单词(或缩写,但缩写往往会造成不明确)进行连接(哪怕这样会很长,Explicit is better than implicit );
- 避免使用容易混淆的字符,比如 l( L 的小写)、O( o 的大写)等;
- 避免采用内置名称、关键字和已经使用过的名称,避免采用过于通用的名称,前者会造成原有功能的屏蔽,后者会造成含义过于广泛而失去明确性;
- 与此同时,还有观点表示应避免使用
tools
、utils
、common
等名称,以及避免使用以object
、manager
/management
、handler
等作为后缀的名称,这些观点中将其称之为反模式,认为这些名称没有起到实际的意义,并且类似utils
的命名反而最终会成为劣质代码的聚集地,并且将这种名称认为是缺乏设计的名称,我们在这里将这些观点当作一种扩展阅读即可;
对于变量(和常量):
- 变量名可小写,也可使用下划线命名;
- 类型变量名(常用于类型提示)应使用大驼峰命名;
- 常量应使用全大写字母,必要时使用下划线分隔,并且要注意在 Python 中并没有类似其他语言中
const
的概念,常量仅仅是一种约定(常量通常放置在代码顶部、或单独的模块、或特定的配置文件中)。对于一组常量,不应使用同一个前缀(这也适用于在同一个类中的方法或者属性),因为这样会和模块名称造成冗余,若多组常量,则针对每一组常量可以使用同一前缀。 - 对于容器类变量,常采用复数名词形式;对于映射类变量,常采用
key_value
的形式,其中key
、value
为键和值的实际含义。 - 对于表示布尔值的变量或者常量(但不仅限于这两者),常采用
has
、is
作为前缀。
对于类(和异常):
- 类名应使用大驼峰命名(这里不包括一些 Python 内置的类,比如
int
、list
),类和属性常采用名词,方法多采用动词或者包含动词。 - 基类常采用
Base
作为前缀,抽象类常采用Abstract
作为前缀。 - 异常名应使用大驼峰命名法,当此异常表示一个错误时,应添加
Error
后缀(并不是所有异常都代表代码运行错误,比如KeyboardInterrupt
、SystemExit
)。
对于函数、方法:
- 函数名、方法名应使用小写,也可使用下划线命名(但我们仍会在一些代码中看到一些方法或者函数名称采用了驼峰命名法,甚至在 Python 的标准库中也存在这样的现象,比如在
threading
模块中,因为这些代码的出现往往早于 PEP 8 规范的诞生,同时为了向后兼容而保留,但通常这些模块都会提供相同功能的以小写加下划线命名的方法,我们应该尽可能使用这些新的方法)。 - 实例方法的首个参数名应为
self
,类方法的首个参数应为cls
(class
作为关键字不能被使用,常被cls
或klass
替换);
对于模块和包:
- 模块( modules )名应尽可能使用小写,在必要时可以使用下划线命名(除了
__init__
模块以外),当使用 C/C++ 编写扩展模块时,通常需要添加下划线前缀; - 包( packages )名应使用小写,最好不要使用下划线;
特殊格式:
- 单下划线前缀,比如
_name
,常称为 ”伪私有属性“(也可用于私有的方法、类等),这种命名方式在 Python 中是一种表示私有属性的约定(同时注意from ... import *
时不会导入这种形式的对象,并且这种伪私有变量通常会通过特定的方法来获取或者赋值),私有属性通常没有直接对外的功能,常用于记录内部状态或用于提供一些公共功能的方法内使用; - 单下划线后缀,比如
name_
,常用于避免和 Python 的关键字发生冲突; - 双下划线前缀,比如
__name
,常用于基类避免和子类中的命名冲突,Python 会通过转换规则将其转换为类似_Class__name
的形式,这种方式通常称为命名修饰 name mangling 或 name decoration(这种方式通常用于多继承,应避免将这种形式用在私有属性的命名上);
class MyClass:
__name = 1
MyClass.__name
Traceback (most recent call last):
Python Shell, prompt 83, line 1
builtins.AttributeError: type object 'MyClass' has no attribute '__name'
- 前后双下划线,比如
__name__
,这是我们之前提到过的 Python 内部常用的 dunder 名称,不应自定义这类命名。
模块尽量使用小写命名,首字母保持小写,尽量不要用下划线(除非多个单词,且数量不多的情况)
# 正确的模块名
import decoder
import html_parser
# 不推荐的模块名
import Decoder
类名使用驼峰(CamelCase)命名风格,首字母大写,私有类可用一个下划线开头
class Farm():
pass
class AnimalFarm(Farm):
pass
class _PrivateFarm(Farm):
pass
将相关的类和顶级函数放在同一个模块里. 不像Java, 没必要限制一个类一个模块.
函数名一律小写,如有多个单词,用下划线隔开
def run():
pass
def run_with_env():
pass
私有函数在函数前加一个下划线_
class Person():
def _private_func():
pass
变量名尽量小写, 如有多个单词,用下划线隔开
if __name__ == '__main__':
count = 0
school_name = ''
常量采用全大写,如有多个单词,使用下划线隔开
MAX_CLIENT = 100
MAX_CONNECTION = 1000
CONNECTION_TIMEOUT = 600
常量使用以下划线分隔的大写命名
MAX_OVERFLOW = 100
Class FooBar:
def foo_bar(self, print_):
print(print_)