阅读本文需要5.5分钟
为什么我们需要PEP 8
“可读性很重要”
— Python的禅宗
Pep 8的存在是为了提高Python代码的可读性。但为什么可读性如此重要呢?为什么编写可读的代码是Python语言的指导原则之一?
正如GuidovanRossum所说,“代码被读的频率比它所写的要多得多。”您可以花几分钟或一整天编写一段代码来处理用户身份验证。一旦你写好了,你就再也不会写了。但你一定得再读一遍。这段代码可能仍然是您正在进行的项目的一部分。每次返回到该文件时,您都必须记住该代码所做的事情以及编写它的原因,因此可读性很重要。
如果您是Python新手,那么在编写代码之后的几天或几周内,很难记住一段代码所做的事情。如果您遵循PEP 8,您可以确保您已经很好地命名了变量。您将知道已经添加了足够多的空白,因此在代码中更容易遵循逻辑步骤。您也会很好地注释您的代码。所有这些都意味着您的代码更加可读性更强,更容易返回。作为初学者,遵循PEP 8的规则可以使学习Python变得更加愉快。
如果你想找一份开发工作,遵循PEP 8尤其重要。编写清晰、可读的代码显示出专业精神。它会告诉雇主你知道如何很好地构造你的代码。
如果您有更多编写Python代码的经验,那么您可能需要与其他人协作。在这里编写可读的代码是至关重要的。其他人,他们可能从来没有见过你或看过你的编码风格,将不得不阅读和理解你的代码。拥有您遵循和认可的指导方针将使其他人更容易阅读您的代码。
命名公约
“明示胜于含蓄。”
— Python的禅宗
在编写Python代码时,必须指出很多事情:变量、函数、类、包等等。选择合理的名字以后会节省你的时间和精力。将能够从名称中了解某个变量、函数或类所代表的内容。您还将避免使用可能导致难以调试的错误的不适当名称。
注*绝不使用l
, O
,或I
这些字母名称可能会被误认为1
和0
,取决于字体:
O = 2 # This may look like you're trying to reassign 2 to zero
命名样式
下表概述了Python代码中的一些常见命名样式以及何时使用它们:
类型 | 命名公约 | 实例 |
function |
使用小写单词。用下划线分隔单词以提高可读性。 | function , my_function |
variable | 使用小写的单个字母、单词或单词。单独的单词与下划线,以提高可读性。 | x , var , my_variable |
class | 每个单词以大写字母开头。不要用下划线分隔单词。这种式样叫做骆驼箱。 | Model , MyClass |
method | 使用小写单词。单独的单词与下划线,以提高可读性。 | class_method , method |
constant | 使用大写字母、单词或单词。单独的单词与下划线,以提高可读性。 | CONSTANT , MY_CONSTANT , MY_LONG_CONSTANT |
module | 使用一个或多个小写单词。单独的单词与下划线,以提高可读性。 | module.py , my_module.py |
package | 使用一个或多个小写单词。不要用下划线分隔单词。 | package , mypackage |
这些是一些常见的命名约定和如何使用它们的示例。但是,为了编写可读的代码,您仍然必须小心选择字母和单词。除了在代码中选择正确的命名样式之外,还必须仔细选择名称。下面是关于如何尽可能有效地做到这一点的几个提示。
如何选择名字
为变量、函数、类等选择名称可能具有挑战性。在编写代码时,应该将相当多的思想放在您的命名选择上,因为它将使的代码更具可读性。在Python中命名对象的最佳方法是使用描述性名称来明确对象所代表的内容。
当命名变量时,您可能会倾向于选择简单的、单字母小写名称,如x
...但是,除非你用x
作为数学函数的论证,不清楚是什么x
代表。假设您将一个人的名字存储为一个字符串,并且您希望使用字符串切片来以不同的格式设置他们的名字。你可能会得到这样的结果:
>>> # Not recommended >>> x = 'John Smith' >>> y, z = x.split() >>> print(z, y, sep=', ') 'Smith, John'
这是可行的,但你必须跟踪x
, y
,和z
代表。对合作者来说,这也可能令人困惑。一个更清晰的名字选择应该是这样的:
>>> # Recommended >>> name = 'John Smith' >>> first_name, last_name = name.split() >>> print(last_name, first_name, sep=', ') 'Smith, John'
同样,为了减少键入量,在选择名称时使用缩写是很有诱惑力的。在下面的示例中,我定义了一个函数db()
这只需要一个论点x
并加倍:
# Not recommended def db(x): return x * 2
乍一看,这似乎是一个明智的选择。db()
很容易成为Double的缩写。但是想象一下几天后回到这个代码。您可能已经忘记了您试图用这个函数实现什么,这将使您很难猜测您是如何缩写它的。
下面的例子要清楚得多。如果您在编写此代码几天后返回,您仍然能够阅读并理解此函数的用途:
# Recommended def multiply_by_two(x): return x * 2
同样的原理也适用于Python中的所有其他数据类型和对象。尽量使用尽可能简洁但描述性最好的名字。
代码布局
“美胜丑”
— Python的禅宗
如何布局代码对代码的可读性有很大的影响。在本节中,您将学习如何添加垂直空格以提高代码的可读性。您还将学习如何处理PEP 8中推荐的79个字符行限制。
空白行
垂直空格或空行可以极大地提高代码的可读性。合并在一起的代码可能会令人难以理解和难以理解。类似地,代码中的空行太多,使其看起来非常稀疏,读者可能需要滚动到不必要的程度。下面是关于如何使用垂直空格的三个关键指南。
用两个空行包围顶层函数和类。顶级函数和类应该是相当独立的,并处理单独的功能。在它们周围放置额外的垂直空间是有意义的,这样就可以清楚地看到它们是分开的:
class MyFirstClass: pass class MySecondClass: pass def top_level_function(): return None
用一个空行包围类中的方法定义。在类中,函数都是相互关联的。在它们之间只留一行是很好的做法:
class MyClass: def first_method(self): return None def second_method(self): return None
在函数中尽量使用空行来显示清楚的步骤。有时,复杂的函数必须在return
声明。为了帮助读者理解函数中的逻辑,在每个步骤之间留一个空行是有帮助的。
在下面的示例中,有一个计算列表方差的函数。这是两个步骤的问题,所以我已经指出了每一步,在它们之间留了一个空行。对象之前还有一个空行。return
声明。这有助于读者清楚地看到返回的内容:
def calculate_variance(number_list): sum_list = 0 for number in number_list: sum_list = sum_list + number mean = sum_list / len(number_list) sum_squares = 0 for number in number_list: sum_squares = sum_squares + number**2 mean_squares = sum_squares / len(number_list) return mean_squares - mean**2
如果您仔细使用垂直空格,它可以极大地提高代码的可读性。它帮助读者直观地理解您的代码是如何划分成部分的,以及这些部分是如何相互关联的。
最大线长与断线
Pep 8建议行限制在79个字符以内。这是因为它允许您在打开多个文件时彼此相邻,同时也避免了行包装。
当然,将语句保持在79个字符或更少的位置并不总是可能的。Pep 8概述了允许语句在几行上运行的方法。
如果代码包含在括号、括号或大括号中,Python将假定行继续:
def function(arg_one, arg_two, arg_three, arg_four): return arg_one
如果不可能使用隐含的延拓,则可以使用反斜杠来断行:
from mypkg import example1, \ example2, example3
但是,如果您可以使用隐含的延拓,那么您应该这样做。
如果需要在二进制运算符周围发生断线,如+
和*
,它应该发生在操作员之前。这个规则源于数学。数学家们一致认为,在二元算子之前的破缺提高了可读性。比较以下两个例子。
下面是在二进制运算符之前中断的示例:
# Recommended total = (first_variable + second_variable - third_variable)
您可以立即看到添加或减去哪个变量,因为运算符就在操作变量的旁边。
现在,让我们看一个二进制操作符之后中断的例子:
# Not Recommended total = (first_variable + second_variable - third_variable)
在这里,很难看出哪些变量被添加,哪些被减去。
在二进制操作符之前中断会产生更易读的代码,因此PEP 8鼓励它。密码始终如一二进制运算符仍然符合PEP 8后中断。但是,我们鼓励您在二进制运算符之前中断。
压痕
“应该有一种--最好只有一种--显而易见的方法。”
— Python的禅宗
缩进(即前导空格)在Python中非常重要。Python中代码行的缩进级别决定了语句是如何组合在一起的。
考虑以下示例:
x = 3 if x > 5: print('x is larger than 5')
凹痕print
语句让Python知道,只有在if
语句返回True
...同样的缩进适用于告诉Python在调用函数时要执行什么代码,或者什么代码属于给定的类。
PEP 8规定的主要缩进规则如下:
- 使用4个连续空格表示缩进。
- 更喜欢空格而不是制表符。
制表符与空格
如前所述,缩进代码时应使用空格而不是制表符。时,可以调整文本编辑器中的设置,以输出4个空格,而不是制表符字符。附签钥匙。
如果您使用Python 2,并且混合了制表符和空格来缩进代码,那么在尝试运行它时不会看到错误。若要帮助您检查一致性,可以添加-t
从命令行运行Python 2代码时标记。当您与使用制表符和空格不一致时,解释器将发出警告:
$ python2 -t code.py code.py: inconsistent use of tabs and spaces in indentation
相反,如果您使用-tt
标志,解释器将发出错误而不是警告,您的代码将不会运行。使用此方法的好处是,解释器将告诉您不一致的地方:
$ python2 -tt code.py File "code.py", line 3 print(i, j) ^ TabError: inconsistent use of tabs and spaces in indentation
Python 3不允许混合制表符和空格。因此,如果使用Python 3,则会自动发出这些错误:
$ python3 code.py File "code.py", line 3 print(i, j) ^ TabError: inconsistent use of tabs and spaces in indentation
您可以编写带有制表符或空格表示缩进的Python代码。但是,如果使用Python 3,则必须与您的选择保持一致。否则,您的代码将无法运行。Pep 8建议您始终使用4个连续空格来表示缩进。
缩进后换行
当您使用行连续性将行保持在79个字符以下时,使用缩进来提高可读性是很有用的。它允许读者区分两行代码和跨越两行代码的一行代码。有两种样式的缩进可以使用。
第一种方法是将缩进块与开始分隔符对齐:
def function(arg_one, arg_two, arg_three, arg_four): return arg_one
有时,您可以发现只需要4个空格就可以与开始分隔符对齐。这种情况经常发生在if
跨多行的语句if
、空格和开始括号由4个字符组成。在这种情况下,很难确定if
声明开始:
x = 5 if (x > 3 and x < 10): print(x)
在这种情况下,PEP 8提供了两个选项来帮助提高可读性:
- 在最后条件之后添加注释。由于大多数编辑器的语法突出显示,这将将条件与嵌套代码分开:
x = 5 if (x > 3 and x < 10): # Both conditions satisfied print(x)
- 在行继续上添加额外的缩进:
x = 5 if (x > 3 and x < 10): print(x)
中断后的另一种缩进样式是悬挂缩进...这是一个排版术语,意思是除了段落或语句中的第一行外,每一行都是缩进的。您可以使用挂起的缩进来直观地表示代码行的延续。下面是一个例子:
var = function( arg_one, arg_two, arg_three, arg_four)
注:当你使用悬挂缩进时,第一行不能有任何争论。以下示例不符合PEP 8:
# Not Recommended var = function(arg_one, arg_two, arg_three, arg_four)
当使用挂起缩进时,添加额外的缩进以区分连续行和函数中包含的代码。下面的示例很难阅读,因为函数中的代码与连续行处于相同的缩进级别:
# Not Recommended def function( arg_one, arg_two, arg_three, arg_four): return arg_one
相反,最好对行继续使用双缩进。这有助于区分函数参数和函数体,提高可读性:
def function( arg_one, arg_two, arg_three, arg_four): return arg_one
当您编写符合PEP 8的代码时,79个字符行限制迫使您在代码中添加换行。为了提高可读性,您应该缩进一个连续行,以显示它是一个连续行。有两种方法可以做到这一点。第一种方法是将缩进块与开始分隔符对齐。二是使用悬吊缩进。在中断行之后,您可以自由选择使用哪种缩进方法。
关闭栏杆的位置
行连续允许您在括号、括号或大括号中分隔行。这是很容易忘记关闭支撑,但重要的是把它放在一个明智的地方。否则,它会混淆读者。Pep 8提供了两个选项,用于在隐含行连续中关闭支撑的位置:
- 用前一行的第一个非空白字符对齐结束大括号:
list_of_numbers = [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
- 将结束大括号与开始构造的行的第一个字符对齐:、
list_of_numbers = [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
您可以自由选择使用的选项。但是,像往常一样,一致性是关键,所以试着坚持上面的方法之一。
评论意见
“如果实施很难解释,那是个坏主意。”
— Python的禅宗
您应该在编写代码时使用注释来记录代码。重要的是记录您的代码,以便您和任何协作者都能够理解它。当您或其他人阅读注释时,他们应该能够轻松地理解该注释适用的代码以及它如何与您的其余代码相匹配。
在向代码中添加注释时,需要记住以下几个要点:
- 将注释和文档字符串的行长度限制为72个字符。
- 使用完整的句子,以大写字母开头。
- 如果更改代码,请确保更新注释。
块注释
使用块注释记录一小部分代码。当您需要编写几行代码来执行单个操作(例如从文件导入数据或更新数据库条目)时,它们非常有用。它们很重要,因为它们帮助其他人理解给定代码块的用途和功能。
Pep 8为编写块注释提供了以下规则:
- 缩进块注释与它们描述的代码级别相同。
- 开始每一行
#
后面跟着一个空格。 - 用一行分隔段落,其中包含一个
#
.
下面是一个解释for
循环。请注意,该句子包含一个新行,以保留79个字符行限制:
for i in range(0, 10): # Loop over i ten times and print out the value of i, followed by a # new line character print(i, '\n')
有时,如果代码非常技术性,那么必须在块注释中使用多个段落:
def quadratic(a, b, c, x): # Calculate the solution to a quadratic equation using the quadratic # formula. # # There are always two solutions to a quadratic equation, x_1 and x_2. x_1 = (- b+(b**2-4*a*c)**(1/2)) / (2*a) x_2 = (- b-(b**2-4*a*c)**(1/2)) / (2*a) return x_1, x_2
在您的代码中尽可能多地使用它们,但是如果您对代码进行更改,请确保更新!