Python的最佳实践和技巧,助您快速有效地编码
Python作为最受初学者欢迎的编程语言之一,是世界各地学校中被最广泛教授的语言。
然而,学习Python并非易事。首先,需要找到最佳的在线学习途径,而这本身就很困难。市面上有成千上万种不同的Python课程和辅导,都声称自己是最好的。
的确,仅凭练习是不够完美的,但完美的练习却是完美的。这意味着,需确保自己始终遵循着最佳编码实践(对代码进行注释、使用正确句法等),反之,则可能会养成一些不良习惯,影响您在编码行业的未来发展。
“通用规范提供了所有的可维护性,清晰性,一致性,也为良好的编程习惯奠定基础。它不能做的就是违背您的意愿,坚持让您学习它。这就是Python!”
— Tim Peters 发表于 comp.lang.python, 2001–06–16
在本篇文章中,我将分享十个帮助您快速有效地用Python进行编码的技巧。
1.可读性的重要性
程序必须为了人们能够读懂而编写,其次使机器能够执行。
Hal Abelson
(https://www.azquotes.com/author/38260-Hal_Abelson)
首先,遵循编程规范,使程序易于阅读。编程规范是经验丰富的程序员在编写其代码时所遵循的。除忽略这些规范外,没有任何其他方式可以更快地证明您是位“新手”。其中一些规范特定于Python;其他则可由计算机程序员用于所有语言中。
来源:Pexels
· 文档字符串= 如何使用代
· 注释=为何代码能(合理)执行和如何执行
文档字符串解释了如何使用代码:
· 解释函数用途,即使对您而言,这个用途十分明显。但以后,其用途对他人来说,不一定同样明显。
· 描述期望参数、返回值及例外情况。
· 如果该类函数与单个Caller紧密耦合,请提及调用函数。
这些注释向代码维护人员说明维护需求。下面的示例也包括给自己的注释,如:
# !!! BUG: …
# !!! FIX: This is a hack
# ??? Why is this here?
编写良好的文档字符串和注释是您的责任,因此请始终使它们保持最新!在进行更改时,请确保注释和文档字符串与代码一致。
您将在“文档字符串惯例”(https://www.python.org/dev/peps/pep-0257/)中找到专门用于文档字符串的详细PEP
5.变量和分配
在其他编程语言中:
c = aa = bb = c
在Python中,最好将分配项放入一个代码行中:
b, a = a, b
您可能已经看到代码,但您知道它如何执行吗?
· 逗号是构造元组的句法。
· 在右侧创建一个元组(元组包)。
· 元组是左侧的目标(元组拆包)。
其他示例:
result = ''for s in colors: result += s
在结构化数据循环中很有用(已保留上述变量名):
result = ' '.join(colors)
也可以采取相反的方式,只需确保左右具有相同的结构即可:
>>> jan, (gname, gtitle, gphone) = people>>> gname'German'>>> gtitle'GBT'>>> gphone'unlisted'>>> jan['Jan', 'Gomez', '+1-888-222-1546']
6.列表拼接&合并
首先从字符串列表开始:
colors = ['red', 'blue', 'green', 'yellow']
我们想将这些字符串连接在一起以创建一条长链。特别是当子字符串的数量很大时,请避免这样做:
result = ''for s in colors: result += s
这样做非常慢。且占用大量内存和性能。总和将累加、存储、然后继续进行每个中间步骤。
取而代之,执行以下操作:
colors = ['red', 'blue', 'green', 'yellow']print ('Choose', ', '.join(colors[:-1]), \ 'or', colors[-1])>> Choose red, blue, green or yellow
join()函数可一次完成整个副本。当仅处理几个字符串时,它与其他函数没有什么区别。却能使您养成使用最佳函数构建长链的习惯,因为面对成百上千的字符串,使用join()函数的确大有不同。
下面是使用join()函数的一些技巧。如果想使用空格作为分隔符:
# Do this : # And not this :if x: if x == True: pass pass# Do this : # And not this :if items: if len(items) != 0: pass pass# and especially not that : if items != []: pass
或逗号和空格:
result = ', '.join(colors)
为了使句子语法正确,除最后一个值之外的每个值之间都使用逗号(人们更喜欢使用“或”)。拆分列表的语法将完成其余工作。[:-1]返回除最后一个值外的所有内容,我们可以将其与逗号连接。
colors = ['red', 'blue', 'green', 'yellow']print ('Choose', ', '.join(colors[:-1]), \ 'or', colors[-1])>> Choose red, blue, green or yellow
7.测试真实条件
就布尔值而言,利用Python既简洁又快速:
# Do this : # And not this :if x: if x == True: pass pass# Do this : # And not this :if items: if len(items) != 0: pass pass# and especially not that : if items != []: pass
8.尽可能使用枚举函数
枚举函数获取一个列表并返回数对(指数,数项):
items = ['zero', 'one', 'two', 'three']>>> print list(enumerate(items))[(0, 'zero'), (1, 'one'), (2, 'two'), (3, 'three')]
使用列表显示结果是必要的,因为枚举函数是一种惰性函数,仅在要求时才一次生成一个数项(一对)。for循环需要这种机制。一次Print函数不会得到任何结果,但必须拥有要显示的完整消息。因此,在使用Print函数之前,我们应自动将生成器转换为列表。
因此,使用下面的循环效果更佳:
>>> [(x, y) for x in (1, 2, 3, 4) if x % 2 == 0 for y in ['a', 'b'] if y == 'b'][(2, 'b'), (4, 'b')]
使用枚举函数的版本比其他两个版本更短,更简单。以上为表明枚举函数返回迭代器的示例(生成器是迭代器的一种)。
9.列表推导式
使用for和if的传统方式:
让我们对小于100的数字平方求和: # With a loop :total = 0for num in range(1, 101): total += num * num
使用列表推导式:
new_list = [fn(item) for item in a_list if condition(item)]
列表推导式清晰直接。在同一个列表推导式中,可以包含几个for循环和if条件,但如果超过两个或三个,或条件十分复杂,我建议您使用普通的for循环。
例如,从0至9的二次幂列表:
>>> [n ** 2 for n in range(10)][0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
上个列表中的奇数列表:
>>> [n ** 2 for n in range(10) if n % 2][1, 9, 25, 49, 81]
更多示例:
>>> [(x, y) for x in (1, 2, 3, 4) if x % 2 == 0 for y in ['a', 'b'] if y == 'b'][(2, 'b'), (4, 'b')]
10.生成器表达式
让我们对小于100的数字平方求和:
让我们对小于100的数字平方求和: # With a loop :total = 0for num in range(1, 101): total += num * num
还可以使用sum函数,通过建立正确的序列来为我们更快地完成工作。
# With a list comprehension :total = sum([num * num for num in range(1, 101)])# With a generator expression :total = sum(num * num for num in xrange(1, 101))
生成器表达式类似于列表推导式,只是在计算时属于懒惰型。列表推导式一次计算整个结果,然后将其存储在列表中。必要时,生成器表达式一次计算一个值。当序列很长并且生成的列表只是中间步骤而不是最终结果时,生成器表达式特别有用。
例如,如果我们必须对数十亿个整数的平方求和,使用列表推导会达到内存的饱和,但使用生成器表达式不会有任何问题。尽管这需要一段时间!
total = sum(num * num for num in range(1, 1000000000))
二者在语法上的差异是列表推导式带有方括号,而生成器表达式则没有。生成器表达式有时需要括号,因此您应始终使用它们。
简而言之: