Python元组在return语句中解压缩

时间:2017-11-13 19:54:27

标签: python python-3.x return tuples iterable-unpacking

Python语言(尤其是3.x)允许迭代的非常通用的解包,其中一个简单的例子是

even[k] = odd[j] = '\0';

多年来,这种拆包已经逐渐推广(参见例如PEP 3132PEP 448),允许它在越来越多的情况下使用。因此,我惊讶地发现以下是Python 3.6中的无效语法(在Python 3.7中仍然如此):

a, *rest = 1, 2, 3

我可以通过将返回的元组封装在括号中来实现它的工作原理:

def f():
    rest = [2, 3]
    return 1, *rest  # Invalid

我在def f(): rest = [2, 3] return (1, *rest) # Valid 语句中使用它的事实似乎很重要,如

return

确实是合法的,无论是否有括号都会产生相同的效果。

这个案例是否被Python开发人员遗忘了,或者这个案例是否有任何理由无效?

为什么我关心

这打破了我认为我使用Python语言的重要合同。考虑以下(也是有效的)解决方案:

t = 1, *rest

通常当我有这样的代码时,我认为def f(): rest = [2, 3] t = 1, *rest return t 是一个临时名称,我应该能够摆脱它只是用它的定义替换底线中的t。但在这种情况下,这会导致无效代码

t

在返回值周围放置括号当然没什么大不了的,但通常需要额外的括号来区分几种可能的结果(分组)。这不是这种情况,因为省略括号不会产生一些其他不需要的行为,而是根本没有行为。

1 个答案:

答案 0 :(得分:26)

我怀疑这是一个意外,基于this commit对Python 3.2的评论。

该提交使赋值表达式能够生成testlist_star_expr生成(允许无表达式解包的内容),但保留了返回语句生成testlist。我怀疑提交错过了这个(可能还有其他地方,但我现在专注于return_stmt制作。)

我继续修改Python Grammar / Grammar文件以允许这个。所有测试都继续通过,包括test_grammar.py文件中的测试(但这似乎并不详尽)。

如果您有点好奇,this is the change I made。随意克隆或下载my fork

更新:我已提交bpo issuepull request作为退货(和收益)解包。