Python语言(尤其是3.x)允许非常广泛地拆解可迭代对象,其中一个简单的示例是
a, *rest = 1, 2, 3
多年来,这种拆包已逐渐普及(例如参见PEP 3132和PEP 448),从而使其可以在越来越多的情况下使用。因此,我很惊讶地发现以下内容在Python 3.6中是无效的语法(在Python 3.7中仍然如此):
def f():
rest = [2, 3]
return 1, *rest # Invalid
我可以通过将返回的元组封装在括号中来使其工作,如下所示:
def f():
rest = [2, 3]
return (1, *rest) # Valid
我在return
声明中使用它的事实似乎很重要,因为
t = 1, *rest
确实是合法的,并且在带括号和不带括号的情况下都相同。
Python开发人员只是忘记了这种情况,还是有任何原因使这种情况成为无效语法?
我为什么在乎
这打破了我以为我与Python语言达成的一项重要合同。考虑以下(也是有效的)解决方案:
def f():
rest = [2, 3]
t = 1, *rest
return t
通常,当我拥有这样的代码时,我认为这t
是一个临时名称,我应该能够摆脱该名称,而只需t
用其定义替换底线即可。但是在这种情况下,这会导致无效代码
def f():
rest = [2, 3]
return 1, *rest
当然,不必在返回值周围放置括号,但是通常只需要附加括号即可区分几种可能的结果(分组)。在这种情况下不是这样,因为省略括号不会产生其他不必要的行为,而根本不会产生任何行为。
更新资料
从Python 3.8(请参阅此列表中的第7项)开始,上面讨论的通用语法现在有效。