在用pycharm编码的过程中,发现会有很多关于编程规范的小提示,虽然之前看了一些python的编码规范,但写起来还是觉得差了很多。
既然自诩了“文艺犯二”,又怎能允许写出来的代码不漂亮呢?
于是花了很多时间搜罗python的编码规范,原来python官网就有啊!深深觉得自己孤陋寡闻了。
PEP: Python Enhancement Proposals(python优化建议)PEP的内容非常的丰富,其中关于编码规范可以参考以下两个index
PEP8: Style Guide for Python Code
https://legacy.python.org/dev/peps/pep-0008/
PEP257:Docstring Conventions
https://legacy.python.org/dev/peps/pep-0257/
================================
原则:编码规范最基本的原则是一致性!
一个项目中的一致性非常重要!
不要为了遵守PEP而破坏向后兼容性。
===============================
代码布局
- 每个级别的缩进使用4个空格。
- 每行最大长度79,文档注释一类的不超过72个字符。换行可以使用反斜杠,也可用()括起一条换行的语句。 换行点要在操作符之前,这样可以保证操作符对齐。
- 关于空行:类和top-level函数定义之间空两行;类中方法定义之间空一行;函数内无关代码段之间空一行;其它地方尽量不要再空行。
- 不要将多条语句写在同一行,虽然python支持用“;”来分隔一行里的多条语句,但仍然不推荐这样写。
- python中的“;”作用就是为了分隔一行中的多条语句,虽然行尾加与不加“;”都可以正常编译,但推荐遵循python的特点,不加“;”
- if/for/while语句中,即使执行语句只有一句,也推荐另起一行。
文档编排
- 模块内容顺序:模块说明& docstring -->import (标准库-> 第三方库->自定义库,之间空一行)–> global&constants -->其它定义。
- 不要在一句import中引入多个库。
空格
- 各种右括号之前不加空格
- 逗号、冒号、分号之前不加空格
- 函数左括号之前不加空格
- 序列左括号之前不加空格
- 操作符左右各加一个空格,不要为了对齐增加空格
- 函数默认参数使用的赋值符左右省略空格
注释
- 错误的注释不如没有注释,所以当修改代码时,第一件事就是修改注释!(这条适用于所有语言)
- 要使用英文,最好是完整的句子,大写开头,句号结尾。
- 块注释:在“#”后加一空格,跟注释。
- 行注释不推荐使用
- 避免无用的注释
文档描述
- 为所有的共有模块、函数、类、方法写docstrings;非共有的没有必要,但是可以写注释(在def的下一行)
命名规范
- 命名尽量从使用的角度而非实现的角度。
- 尽量避免使用小写字母‘l’,大写字母‘O’等容易混淆的字母。
- 模块命名尽量短小,使用全部小写的方式,可以使用下划线。
- 包命名尽量短小,使用全部小写的方式,不可以使用下划线。
- 类的命名使用CapWords的方式,模块内部使用的类采用_CapWords的方式。
- 异常命名使用CapWords+Error后缀的方式。
- 全局变量尽量只在模块内有效,类似C语言中的static。实现方法有两种,一是__all__机制;二是前缀一个下划线。放在模块的docstring和from __future__之后,import之前。
- 函数命名使用全部小写的方式,可以使用下划线分隔语意。
- 常量命名使用全部大写的方式,可以使用下划线。
- 类的属性(方法和变量)命名使用全部小写的方式,可以使用下划线。
- 类的属性有3种作用域public、non-public和subclass ,可以理解成C++中的public、private、protected,non-public属性前,前缀加一个下划线。
- 类的属性若与关键字名字冲突,后缀加下划线,尽量不要使用缩略等其他方式。
- 为避免与子类属性命名冲突,在类的一些属性前,前缀两条下划线。比如:类Foo中声明__a,访问时,只能通过Foo._Foo__a,避免歧义。如果子类也叫Foo,那就无能为力了。
- 类的方法第一个参数必须是self,而静态方法第一个参数必须是cls。
关于import
import bench # 此为 implicit relative import
from . import bench # 此为 explicit relative import
from furniture import bench # 此为 absolute import
第一种隐式相对导入,python3已经废弃,只能用于导入path中的模块
第二种显示相对导入
第三种绝对导入,是推荐的import方式。
跨行语句示例
<示例1>
# 与打开的括号对齐
foo = long_function_name(var_one, var_two,
var_three, var_four)
# 悬挂式,首行无参数
foo = long_function_name(
var_one, var_two,
var_three, var_four)
<示例2>
# 加一行注释,增加可读性
# supporting syntax highlighting.
if (this_is_one_thing and
that_is_another_thing):
# Since both conditions are true, we can frobnicate.
do_something()
# 在续行上增加一级缩进
if (this_is_one_thing
and that_is_another_thing):
do_something()
<示例3>
# 打开的右括号在最后一行对齐第一个非空格字符
my_list = [
1, 2, 3,
4, 5, 6,
]
result = some_function_that_takes_arguments(
'a', 'b', 'c',
'd', 'e', 'f',
)
推荐&不推荐
== YES ==>
def foo(x):
if x >= 0:
return math.sqrt(x)
else:
return None
def bar(x):
if x < 0:
return None
return math.sqrt(x)
<== NO ==
def foo(x):
if x >= 0:
return math.sqrt(x)
def bar(x):
if x < 0:
return
return math.sqrt(x)
== YES ==>
if foo.startswith('bar'):
<== NO ==
if foo[:3] == 'bar':
== YES ==>
if isinstance(obj, int):
<== NO ==
if type(obj) is type(1):
# 空序列为false
== YES ==>
if not seq:
if seq:
<== NO ==
if len(seq):
if not len(seq):