Python语言(尤其是3.x)允许非常通用的unpacking个iterables,一个简单的例子是
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
当然,在返回值周围加括号没什么大不了的,但通常只需要额外的括号来区分几个可能的结果(分组).这里的情况并非如此,因为省略括号不会产生其他一些不想要的行为,而是根本不会产生任何行为.
使现代化
由于Python3.8(参见this list中的第7项),上面讨论的通用语法现在是有效的.