我只花了一天的时间来找到一个错误的逗号引起的错误。寻找我的bug的困难因为第三方回调库加剧了异常而加剧,但它让我想知道为什么Python(2.x)不会引发语法错误而不是创建元组。请考虑以下
>>> a = 1,
>>> a
(1,)
如您所见,尾随逗号创建一个单例元组。这并不违反Python语法(参见http://docs.python.org/reference/expressions.html#grammar-token-expression_list),但它肯定会导致一些意想不到的结果,例如
>>> a == 1,
(False,)
VS
>>> (1,) == a
True
虽然我现在明白发生了什么,但我很困惑为什么Python允许这种语法而不是要求显式括号来创建元组。 在某种情况下,这种行为是必要的,或者至少是有利的吗?在过去的7年里,我几乎完全用Python编程,而且我从来不需要以这种方式创建单例。在大多数方面,Python是一种非常易读和明确的语言。这个特殊的“特征”似乎是非Pythonic。
答案 0 :(得分:7)
这里是Python的创建者Guido van Rossum,explaining这句语法是如何形成的:
向元组添加类似数组的接口的一个结果就是我 必须找出一些方法来解决元组的边缘情况 长度为0或1.我从ABC获取的规则之一是每个数据 类型,当打印或转换为字符串时,应表示为 表达式,是语言解析器的有效输入。所以 接下来我需要有0和1长度元组的符号。 同时我不想失去a之间的区别 一元组和一个简单的括号表达式,所以我选择了一个 丑陋但务实的方法,一个尾随的逗号会变成一个 表达成一元组和"()"将代表一个零元组。 通常不需要括号,这是值得的 Python的元组语法,除了这里 - 我觉得代表空 “没有”的元组太容易掩盖真正的拼写错误。
另见TupleSyntax上的这个PythonInfo Wiki,特别是" ...定义元组"的是逗号,而不是括号。
虽然这种语法并不美观(Guido说丑陋但又务实),但我认为这不是一个问题。真正的问题是,你的第三方图书馆是"诱捕异常"从而隐藏有关错误的重要信息。
答案 1 :(得分:2)
有一个例子,它可以派上用场,交换两个值。当然你可以在这里使用明确的括号,但没有它们看起来会更好。
a, b = b, a
答案 2 :(得分:2)
抱歉,我没有足够的代表发表评论,所以这就是它自己的答案。
这里有两个相关但不同的东西 - 元组解包并只创建一个元组文字。
在Mark Ransom的回答中找到了元组拆包。
元组虽然似乎是人们的绊脚石。它们不是用括号创建的,括号仅用于消除歧义。逗号定义了一个元组,因此a,
是一个带有一个元素的元组,因为,这就是一个元组,一个带逗号的东西:)。 (需要注意的是,对于空元组,而不是看起来很丑的,
,我们会遇到()
,这可能是人们似乎对此有困难的根源。)