Python 逗号的巧用

如果需要在Python中的列表、字典或集合常量中添加或移除项,记住一个窍门:在所有行后面都添加一个逗号。

还不太明白?来看一个示例。假设在代码中有下面这个由名字组成的列表:

>>> names = ['Alice', 'Bob', 'Dilbert']

在修改这个名字列表时,通过git diff查看改动可能有点不方便。大多数源码控制系统都是基于行的,因此无法标出同一行中的多个改动。

一个快速改进是根据编码规范,将列表、字典或集合常量分割成多行,如下所示:

>>> names = [
...     'Alice',
...     'Bob',
...     'Dilbert'
... ]

这样每项独占一行,因此可以清楚地从源码控制系统的diff中看出哪里进行了添加、删除和修改操作。虽然只是一个小改动,但我发现这有助于避免很多愚蠢的错误,也让团队成员能够更方便地审阅我的代码改动。

但现在依然有两个编辑情形会导致混乱,即在列表末尾添加或移除内容时,还需要手动调整逗号来保持格式的一致性。
比如需要向列表中添加一个名字Jane,则需要在Dilbert这一行的末尾添加一个逗号来避免一个讨厌的错误:

>>> names = [
...     'Alice',
...     'Bob',
...     'Dilbert' # <- 缺失逗号!
...     'Jane'
]

在查看这个列表的内容时,请做好心理准备:

>>> names
['Alice', 'Bob', 'DilbertJane']

可以看到,Python将字符串DilbertJane合并成了DilbertJane。这称为字符串字面值拼接,是文档中有记录的刻意行为。这种行为可能会在程序中引入令人难以琢磨的bug:

以空白符分隔多个相连的字符串或byte字面值,即使它们各自使用不同的引号,也会执行拼接操作。

详见Python文档:“String literal concatenation”。

在某些情况下,字符串字面值拼接是一个有用的特性。例如,在跨越多行的长字符串中可以省去反斜杠:

my_str = ('This is a super long string constant '
          'spread out across multiple lines. '
          'And look, no backslash characters needed!')

但另一方面,这个特性有时又会成为负担。那么如何解决这个问题呢?

Dilbert后添加缺失的逗号就能避免两个字符串合并了:

>>> names = [
...     'Alice',
...     'Bob',
...     'Dilbert',
...     'Jane'
]

现在回到原来的问题。为了向列表添加一个新名字,需要修改两行代码。这同样让开发人员很难从git diff看出到底做了什么改动:到底是添加了一个新名字,还是修改了Dilbert这个名字?

幸运的是Python语法留有余地,让我们可以一劳永逸地解决这个逗号放置问题。只要遵循一种能够避免这个问题的编码风格即可,下面来看具体方法。

在Python中,可以在列表、字典和集合常量中的每一项后面都放置一个逗号,包括最后一项。因此只要记住在每一行末尾都加上一个逗号,就可以避免逗号放置问题。

下面是示例的最终版:

>>> names = [
...     'Alice',
...     'Bob',
...     'Dilbert',
... ]

看到Dilbert后面的那个逗号了吗?现在能方便地添加或移除新的项,无须再修改逗号了。这不仅让各行代码保持一致,而且源码控制系统生成的diff清晰整洁,让代码审阅者心情愉悦。看到没,有时魔法就藏在这些细微之处。

关键要点

  • 合理的格式化及逗号放置能让列表、字典和集合常量更容易维护。

  • Python的字符串字面值拼接特性既可能带来帮助,也可能引入难以发现的bug。

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程