代码的整体布局主要囊括了代码在整体结构上应该注意的事项
缩进 空格/制表符
- Python 在语法上使用缩进来确定代码块的开始和结束
- 对于每一级缩进,应为 4 个空格,并且不要混用空格与制表符
- 缩进本身是一种语法上的限制,是强制性的
- 有的IDE会强制用tab进行缩进,并且在编译的时候转换为4个空格
悬挂缩进
- 括号内第一行不应放置元素
- 同级别的代码处于相同的缩进
-
当 if 等控制语句的条件部分需要换行时,可以使用括号将条件部分包裹起来,在括号内进行换行。
-
当多行结构在结束时,其右括号可以另起一行与前一行元素的第一个字符对齐或与第一行元素第一个字符对齐。
# 括号内第一行不应放置元素
def function_name(
var_one,
var_two,
var_three,
var_four
):
print(var_one, var_two, var_three, var_four)
# 同级别的代码处于相同的缩进
a = function_name(
1,
2,
)
# 使用括号将条件部分包裹起来,在括号内进行换行
if (
cond1 and
cond2
):
pass
# 右括号另起一行 与第一行的第一个字符对齐
one_list = [
1, 2, 3,
4, 5, 6
]
行最大长度
所有行的最大长度应限制在 79 个字符以内,文档字符串和注释的最大长度应限制在 72 个字符以内。当一个代码行的长度超过限制时应进行换行,换行应优先使用括号内隐式换行,其次才是使用反斜杠。with 中有多个语句时,可使用反斜杠。
# 应优先使用括号内隐式换行
if (
condition_one and
condition_two
):
pass
# 不提倡下面的方式
if cond1 and \
cond2:
pass
# 下面 with 中有多个语句时,可使用反斜杠。
with open(path_one) as file_one, \
open(path_one) as file_two:
pass
公式很长时的换行
在二元运算符之前换行
result = (var_one
- var_two
+ (var_three * var_four)
- var_five)
代码之间的换行
- 模块级函数和类定义之间空两行;
- 类成员函数之间空一行;
- 可以使用多个空行分隔多组相关的函数
- 函数中可以使用空行分隔出逻辑相关的代码
导入import
- 导入的位置应在该文件头部,位于模块注释和文档字符串之后,全局变量和常量之前
- 对不同包或模块的导入,在代码结构上应该位于不同的行。针对同一个包或模块中进行的多个导入,可以位于同一行
- 如果你的代码中有多个导入,那么组织导入的整体顺序应首先为标准库导入,接着是相关第三方库导入,最后是本地代码导入。这三个部分之间可以用一个空行隔开
- 对于导入的形式,选择
import <module>.<name>
、from <module> import <name>
、from .<module> import <name>
均可(前两种形式称为绝对导入,最后一种称为相对导入或显式相对导入)。
- 推荐优先使用绝对路径进行导入(即绝对导入,absolute imports ),绝对导入的方式更具可读性,并且在导入系统配置不正确时可以表现得更好,比如给出更加清晰可读的错误信息。
- 在处理布局较为复杂的导入时,绝对路径的导入写法可能会造成导入语句过长,这时可考虑使用显式相对导入( explicit relative imports ),应避免使用隐式相对导入( implicit relative imports )
- 尽量避免使用
from <module> import *
的通配符导入写法,通配符导入的写法会使当前的命名空间变得混乱,可能会造成不必要的混淆。
- PyCharm 组织导入的快捷键
Ctrl + Shift + O
调整导入的顺序
代码的编码声明
编码声明指的是类似 #coding: <encoding name>
形式的声明
dunder 方法的位置
dunder 的含义,它是一个合成词,即双下划线 double-underscore 。dunder 方法便指的是 Python 中的特殊方法,也可称为魔术方法,这些方法以双下划线开始和结尾,在运算符重载、数据结构定义中起着重要的作用,常规方法来说,不应使用这种双下划线开始和结尾的形式
"""
module docstrings
"""
from __future__ import unicode_literals
__all__ = ['testa', 'testb']
__version__ = '1.0'
__author__ = 'zhangsan'
import json
引号、空格与逗号
单引号还是双引号?
对单引号和双引号没有特殊的使用要求,它们的作用是相同的
-
自然语言 使用双引号
"..."
例如错误信息;很多情况还是 unicode,使用u"你好世界"
-
机器标识 使用单引号
'...'
例如 dict 里的 key
-
正则表达式 使用原生的双引号
r"..."
-
文档字符串 (docstring) 使用三个双引号
"""......"""
# 当一个字符串需要包含单或双引号时,应使用与最外层不同的引号,
# 来避免进行转义(转义会降低代码的可读性)
my_name = 'my name is "python"'
# 不提倡下面的方式
my_name = 'my name is \'python\''
表达式和语句中的空格
- 在二元运算符两边各空一格
[=,-,+=,==,>,in,is not, and]
:
- 函数的参数列表中,
,
之后要有空格
- 函数的参数列表中,默认值等号两边不要添加空格
- 左括号之后,右括号之前不要加多余的空格
- 字典对象的左括号之前不要多余的空格
# 正确的写法
i = i + 1
submitted += 1
x = x * 2 - 1
hypot2 = x * x + y * y
c = (a + b) * (a - b)
# 不推荐的写法
i=i+1
submitted +=1
x = x*2 - 1
hypot2 = x*x + y*y
c = (a+b) * (a-b)
# 正确的写法
def complex(real, imag):
pass
# 不推荐的写法
def complex(real,imag):
pass
# 正确的写法
def complex(real, imag=0.0):
pass
# 不推荐的写法
def complex(real, imag = 0.0):
pass
# 正确的写法
spam(ham[1], {eggs: 2})
# 不推荐的写法
spam( ham[1], { eggs : 2 } )
# 正确的写法
dict['key'] = list[index]
# 不推荐的写法
dict ['key'] = list [index]
# 正确的写法
x = 1
y = 2
long_variable = 3
# 不推荐的写法
x = 1
y = 2
long_variable = 3
在多数场景中不应使用无关的空格
function_name('test', [1, 2, 3])
# 不提倡下面的方式
function_name( 'test' , [1, 2, 3] )
- 在切片操作中,冒号两边的空格数量应相同;
- 在扩展切片(
step
,称之为步长,默认为 1 )中,两个冒号应使用相同的空格数量;
- 当切片中的某个参数被省略时,对应位置不应使用空格
my_list[1:6], my_list[var_one + var_two : var_three + var_four]
my_list[1:6:2], my_list[: func_one(var_one) : func_two(var_two)]
# 不提倡下面的方式
my_list[1 :6], my_list[var_one + var_two:var_three + var_four]
my_list[1:6 :2], my_list[ : func_one(var_one) : func_two(var_two)]
不应为了对齐等号使用无关的空格
var_one = 1
long_var_two = 2
# 不提倡下面的方式
var_one = 1
long_var_two = 2
在函数中,对于形参列表中的默认参数以及函数调用时的关键字参数,其 =
两侧不应使用无关空格。
def function_one(var_one=True):
return var_one
function_one(var_one=False)
在运算符两侧合理使用空格
在赋值、增强型赋值、比较、布尔等二元运算符两侧应使用空格
var_one = 1
var_two = var_one + 1
var_one += 1
在同时使用不同优先级的运算符时,可在最低优先级的运算符两侧使用空格。对于一些比较复杂的场景下,需要我们来自己定夺空格的使用
var_two = var_one*3 + 1
var_five = var_one*var_two + var_three*var_four
# 注意下面的情况,PEP 8 把这种情况交由我们自己定夺,但仍给出了类似下面的示例供我们参考
var_five = (var_one+var_two) * (var_three+var_four)
# 不提倡下面的方式
var_five = (var_one + var_two) * (var_three + var_four)
在函数注解中合理使用空格
在函数注解中,冒号前不应使用无关空格,->
两侧应使用空格
def function_one(var_one: bool) -> int:
if var_one:
ret = 1
else:
ret = -1
return ret
当函数注解和默认参数同时存在于同一参数时,在 =
两侧应使用空格
def function_one(var_one: bool = True, var_two=False) -> int:
pass
行尾部的逗号
当你想要获得包含一个元素的元组时,应在表达式尾部添加逗号,并最好将其包裹在圆括号内
var_one = (1,)
# 最好不使用下面的方式
var_one = 1,
对于某些包含参数并需要不断扩展的序列,在添加每个参数时,在其尾部也可添加逗号,这样可以规避一些难以发现的问题(请不要小看下方代码所示的问题,当它隐藏在某一段代码中时,你就会感到十分头疼)
# 当在新行中添加参数时,在尾部添加逗号有利于后续扩展,比如可避免漏写上一行结尾处逗号的问题
BACKENDS = (
'BackendOne',
'BackendTwo',
)
# 在扩展时若漏写第二行结尾处的逗号,IDE 中也不会有任何提醒,但会导致无法正常使用该数据
BACKENDS = (
'BackendOne',
'BackendTwo'
'BackThree'
)
复合语句
复合语句是指包含其他语句的语句,比如函数和类的定义、if
、while
、for
、try
、with
等语句,不应将整个复合语句或复合语句中的一部分放置在一行
if var_one == 1:
pass
# 不提倡下面的方式
if var_one == 1: pass