教你一招,提升你Python代码的可读性,小技巧_comparison to `none` should be `cond is none`

本文详细解释了Python编程中的缩进规则(包括悬挂缩进),以及如何使用PEP8标准进行代码格式化,包括块注释、行注释、文档字符串的使用和空格的最佳实践。还介绍了如何使用linters如flake8和pycodestyle来强制代码符合PEP8风格。
摘要由CSDN通过智能技术生成
x = 5
if (x > 3 and
 x < 10):
 # Both conditions satisfied
 print(x)

  1. 在换行中添加额外的缩进
x = 5
if (x > 3 and
 x < 10):
 print(x)

第二个换行符后缩进方式是悬挂缩进

这意味着除了段落或语句中的第一行之外的每一行都是缩进的。你可以使用悬挂缩进来直观地表示代码行延续。下面一个例子:

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为右中括号的位置提供了两个选项:

  1. 使用前一行的第一个非空白字符排列右括号:
list_of_numbers = [
 1, 2, 3,
 4, 5, 6,
 7, 8, 9
 ]

  1. 将右括号与构造开始行的第一个字符对齐:
list_of_numbers = [
 1, 2, 3,
 4, 5, 6,
 7, 8, 9
]

可以自由选择使用的选项,但一致性是关键,所以尽量坚持上述方法之一。

注释

注释代码非常重要,这样你和任何协作者都可以理解它。当你或其他人阅读评论时,他们应该能够轻松理解注释所对应的代码以及它与其余代码的匹配程度。

以下是在为代码添加注释时要记住的一些要点:

  • 将注释和文档字符串的行长限制为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, '
')

有时,如果代码是非常技术性的,那么有必要在块注释中使用多个段落:

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

如果你对使用哪种注释类型更适合存在疑问,那么块注释通常是可行的方法。尽可能在整个代码中使用它们,但如果你对代码进行了更改,也请务必更新它们。

行注释

行注释解释了一段代码中的单个语句。它们有助于提醒你,或向其他人解释为什么需要某行代码。以下是PEP 8对它们的建议:

  • 与代码写在同一行;
  • 使用两个或多个空格将代码与行注释分开;
  • #后加单个空格,然后进行行注释;
  • 不要用它们来解释已经很明显的问题;

以下是行注释的示例:

x = 5 # This is an inline comment

有时,行注释似乎是必要的,但你可以使用更好的命名规则。比如,这是一个例子:

x = 'John Smith' # Student Name

这里,行注释确实提供了额外的信息。但是,使用x作为人名的变量名是不好的做法。如果重命名变量,则无需行注释:

student_name = 'John Smith'

最后,像这样的行注释是不好的做法,因为它们注释了明显且混乱的代码:

empty_list = [] # Initialize empty list
x = 5
x = x * 5 # Multiply x by 5

行注释比块注释更具体,但很容易在不需要时添加它们,这会导致混乱,而你可以总是使用块注释,而不必担心这些。因此,除非确定需要使用行注释,否则更多使用块注释,则代码更可能符合PEP 8。

文档字符串

文档字符串是用双(“”")或单引号(‘’')括起来的字符串,它们出现在任何函数,类,方法或模块的第一行。你可以使用它们来解释和记录一个特定的代码块。

适用于文档字符串的最重要规则如下:

  • 环绕文档字符串,两边都有三个双引号,如 “”" 这是一个文档字符串 “”";
  • 为所有公共模块,函数,类和方法编写它们;
  • 将单行结束多行文档字符串的 “”" 放在一行上:
def quadratic(a, b, c, x):
 """Solve quadratic equation via the quadratic formula.
 A quadratic equation has the following form:
 ax**2 + bx + c = 0
 There always two solutions to a quadratic equation: x_1 & 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

  • 对于单行文档字符串,请将 “”" 保留在同一行:
def quadratic(a, b, c, x):
 """Use the quadratic formula"""
 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

表达式和语句的空格

空格在表达式和语句中正确使用时非常有用。如果没有足够的空白,那么代码可能难以阅读,因为它们都聚集在一起。如果空白太多,那么在语句中可能难以在视觉上组合相关术语。

二元运算符两边的空白

以下二元运算符两边都有一个空格:

  • 赋值运算符(=,+=, -=)
  • 比较运算符(==,=!,>,<,>=,<=)和(is,is not,in,not in)
  • 布尔运算法(and,not,or)

如果语句中有多个运算符,则在每个运算符之前和之后添加单个空格可能会让人感到困惑。相反,最好只在优先级最低的运算符两边添加空格,尤其是在执行数学运算时。以下是几个例子:

# Recommended
y = x**2 + 5
z = (x+y) * (x-y)
# Not Recommended
y = x ** 2 + 5
z = (x + y) * (x - y)

你还可以将此应用于有多个条件的if语句:

# Not recommended
if x > 5 and x % 2 == 0:
 print('x is larger than 5 and divisible by 2!')

在上面的示例中,and 运算符具有最低优先级。因此,可以更清楚地表达if语句如下:

# Recommended
if x>5 and x%2==0:
 print('x is larger than 5 and divisible by 2!')

你可以自由选择哪个更清晰,但需要注意的是必须在运算符的任何一侧使用相同数量的空格。以下是不可接受的:

# Definitely do not do this!
if x >5 and x% 2== 0:
 print('x is larger than 5 and divisible by 2!')

在切片中,冒号充当二元运算符。因此,上面所说的规则同样适用,任何一方都应该有相同数量的空白。以下列表切片示例:

list[3:4]
# Treat the colon as the operator with lowest priority
list[x+1 : x+2]
# In an extended slice, both colons must be
# surrounded by the same amount of whitespace
list[3:4:5]
list[x+1 : x+2 : x+3]
# The space is omitted if a slice parameter is omitted
list[x+1 : x+2 :]

何时避免添加空格

在某些情况下,添加空格会使代码更难以阅读。太多的空格会使代码过于稀疏而难以理解。PEP 8总结了空白不合适的非常明显的例子。

避免添加空格的最重要的地方是在一行的末尾,这称为尾部空格。它是不容易察觉的,可能产生难以追踪的错误。

以下总结了一些应避免添加空格的情况:

  • 紧靠括号,括号或大括号内:
# Recommended
my_list = [1, 2, 3]
# Not recommended
my_list = [ 1, 2, 3, ]

  • 在逗号,分号或冒号之前:
x = 5
y = 6
# Recommended
print(x, y)
# Not recommended
print(x , y)

  • 在打开函数调用的参数列表的开括号之前:
def double(x):
 return x * 2
# Recommended
double(3)
# Not recommended
double (3)

  • 在开始索引或切片的开括号之前:
# Recommended
list[3]
# Not recommended
list [3]

  • 在末尾逗号和右括号之间:
# Recommended
tuple = (1,)
# Not recommended
tuple = (1, )

  • 要对齐赋值运算符:
# Recommended
var1 = 5
var2 = 6
some_long_var = 7
# Not recommended
var1 = 5
var2 = 6
some_long_var = 7

确保代码中的任何位置都没有尾部空格。在其他情况下,PEP 8不鼓励添加额外的空格,例如立即在括号内,以及逗号和冒号之前。你也应该永远不要添加额外的空格为了对齐运算符。

编程建议

你经常会发现有几种方法可以在Python中执行相同的操作(以及任何其他编程语言)。下面你将看到PEP 8提供的一些建议,以消除这种歧义并保持一致性。

**1. 不要使用等价运算符==将布尔值与True或False进行比较。**你经常需要检查布尔值是True还是False。

# Not Recommended
my_bool = 6 > 5
if my_bool == True:
 return '6 is bigger than 5'

这里不需要使用等价运算符==,bool只能取值True或False,因此写下面的内容就足够了,这种使用布尔值执行if语句的方法需要更少的代码并且更简单。

# Recommended
if my_bool:
 return '6 is bigger than 5'

**2. 在if语句中直接判断空序列是否为假。**如果要检查列表是否为空,则可能需要检查列表的长度。如果列表为空,则其长度为0,在if语句中使用时等于False。这是一个例子:

# Not Recommended
my_list = []
if not len(my_list):
 print('List is empty!')

但是,在Python中,任何空列表,字符串或元组都是假的。因此,我们可以给出一个更简单的替代方案:

# Recommended
my_list = []
if not my_list:
 print('List is empty!')

虽然两个例子都打印出来了,第二个选项更简单,所以PEP 8鼓励使用它。

**3. 在if语句中使用 is not 而非 not…is。**如果你要检查变量是否具有已定义的值,则有两个选项。第一个是使用 x is not None,如下例所示:

# Recommended
if x is not None:
 return 'x exists!'

第二种选择是 x is None,然后根据 not 结果得到if语句:

# Not Recommended
if not x is None:
 return 'x exists!'

虽然两个选项都将被正确评估,但第一个选项更简单。

**4. 当你的意思是x is not None 的时候,不要使用if x。**有时,你可能拥有一个默认情况下参数为None的函数。检查这样的参数arg是否被赋予不同值时常见的错误是使用以下内容:

# Not Recommended
if arg:
 # Do something with arg...

此代码检查arg是否为真。相反,你要检查arg是否为None,因此最好使用以下内容:

# Recommended
if arg is not None:
 # Do something with arg...

这里犯的错误是假设了 not None和 truthy 是等价的。你可以设置arg = []。如上所述,空列表在Python中被评估为假的。因此,即使已经分配了参数arg,也不满足条件,因此不会执行if语句主体中的代码。

**5. 使用.startswith()和.endswith()而不是切片。**如果你尝试检查字符串单词是否带有前缀或带有后缀的单词cat,那么使用列表切片似乎是明智的。但是,列表切片容易出错,你必须对前缀或后缀中的字符数进行硬编码。对于那些不太熟悉Python列表切片的人来说,你还想要实现的目标也不清楚:

# Not Recommended
if word[:3] == 'cat':
 print('The word starts with "cat"')

然后,这不像使用.startswith()那样可读:

# Recommended
if word.startswith('cat'):
 print('The word starts with "cat"')

当检查后缀时,同样的原则也适用。下面的示例总结了如何检查字符串是否以jpg结尾:

# Not Recommended
if file_name[-3:] == 'jpg':
 print('The file is a JPEG')

虽然结果是正确的,但符号有点难以阅读。相反,你可以使用.endswith(),如下例所示:

# Recommended
if file_name.endswith('jpg'):
 print('The file is a JPEG')

与大多数这些编程建议一样,目标是可读性和简单性。在Python中,有许多不同的方法可以执行相同的操作,因此有关选择哪种方法的指南很有帮助。

何时忽略PEP 8?

对这个问题的回答:永远不会。如果遵循PEP 8,可以保证你将拥有干净,专业和可读的代码。这将使你以及合作者和潜在雇主都受益。

但是,在以下情况下,PEP 8中的某些指南很不方便:

  • 如果遵守PEP 8将破坏与现有软件的兼容性;
  • 如果围绕你正在处理的内容的代码与PEP 8不一致;
  • 如果代码需要与旧版本的Python保持兼容;

帮助你的代码遵循PEP 8的提示和技巧

PEP 8标准有很多内容,在开发代码时,记住所有这些规则可能是一项艰巨的任务。将过去的项目更新为符合PEP 8特别耗时。幸运的是,有些工具可以帮助加快这一过程。你可以使用两类工具来强制执行PEP 8:lintersautoformatters

Linters

Linters是分析代码和标记错误的程序,它提供了有关如何修复错误的建议。当作为文本编辑器的扩展安装时,Linters特别有用,因为它们在你编写时标记错误和样式问题。下面你将看到Linkers的工作原理,然后和文本编辑器扩展的链接。

最好Linters的Python代码如下:

pycodestyle是一个根据PEP 8中的某些样式约定来检查Python代码的工具。使用pip安装pycodestyle:

$ pip install pycodestyle

可以使用以下命令终端运行pycodestyle:

$ pycodestyle code.py
code.py:1:17: E231 missing whitespace after ','
code.py:2:21: E231 missing whitespace after ','
code.py:6:19: E711 comparison to None should be 'if cond is None:'

flake8是一个结合了debugger,pyflakes和pycodestyle的工具。使用pip安装flake8:

文末有福利领取哦~

👉一、Python所有方向的学习路线

Python所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。img

👉二、Python必备开发工具

img
👉三、Python视频合集

观看零基础学习视频,看视频学习是最快捷也是最有效果的方式,跟着视频中老师的思路,从基础到深入,还是很容易入门的。
img

👉 四、实战案例

光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。(文末领读者福利)
img

👉五、Python练习题

检查学习结果。
img

👉六、面试资料

我们学习Python必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有阿里大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。
img

img

👉因篇幅有限,仅展示部分资料,这份完整版的Python全套学习资料已经上传

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里无偿获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值