Python语言(尤其是3.x)允许非常通用的unpacking个iterables,一个简单的例子是

a, *rest = 1, 2, 3

多年来,这种拆包方式逐渐得到推广(参见PEP 3132PEP 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项),上面讨论的通用语法现在是有效的.

推荐答案

根据this commit对Python 3.2的 comments ,我怀疑这是一个意外.

这个commit使赋值表达式获得了testlist_star_expr个生产(这允许无主题的解包),但让return语句获得了testlist个生产.我怀疑commit刚刚错过了这个(可能还有其他地方,但我现在关注的是return_stmt的制作).

我继续修改了Python语法/语法文件,以允许这样做.所有的测试都继续通过,包括test_grammar.py文件中的测试(但这似乎并不是非常详尽).

如果你好奇的话,this is the change I made.请随意克隆或下载my fork.

UPDATE:我已经提交了一份bpo issue和一份pull request的退货(和退换货)拆包申请.

Python-3.x相关问答推荐

math. gcd背后的算法是什么,为什么它是更快的欧几里得算法?

我在创建Pandas DataFrame时感到困惑

动态范围内来自另外两列的列求和

我想判断df_entry_log[AM_PM],并根据测试填充列

新行是pandas数据帧中旧行的组合

Python GUI:tkinter应用程序作为Windows的实时桌面

如何在 python 中将带有时区信息的时间戳转换为 utc 时间

在python中将字符串写入文本文件

通过最接近的匹配合并两个不同长度的列上的两个数据框

参数化泛型不能与类或实例判断一起使用

python 3中的SQLAlchemy ER图

python 3.7 websockets的1006连接异常关闭错误

Python3四舍五入到最接近的偶数

全局捕获快速 api 中的异常

Jupyter Notebook - 在函数内绘图 - 未绘制图形

如何用pymongo连接远程mongodb

所有 Python dunder 方法的列表 - 您需要实现哪些方法才能正确代理对象?

matplotlib - 模块sip没有属性setapi

同步调用协程

新项目:Python 2 还是 Python 3?