Python语言(尤其是3.x)允许迭代的非常通用的解包,其中一个简单的例子是
even[k] = odd[j] = '\0';
多年来,这种拆包已经逐渐推广(参见例如PEP 3132和PEP 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
在返回值周围放置括号当然没什么大不了的,但通常需要额外的括号来区分几种可能的结果(分组)。这不是这种情况,因为省略括号不会产生一些其他不需要的行为,而是根本没有行为。
答案 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 issue和pull request作为退货(和收益)解包。