当前位置: 首页 > 知识库问答 >
问题:

为什么在Python 3.8之前,在返回语句中加星号的iterable解包没有括号,语法无效?

山阳辉
2023-03-14

Python语言(尤其是3.x)允许对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/c>是一个临时名称,我应该能够用它的定义来简单地将它替换为<代码> t>代码>。但在这种情况下,这会导致无效代码

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

当然,在返回值周围加括号没什么大不了的,但通常只需要额外的括号来区分几个可能的结果(分组)。这里的情况并非如此,因为省略括号不会产生其他一些不想要的行为,而是根本不会产生任何行为。

自Python 3.8以来(参见列表中的第7项),上面讨论的广义语法现在是有效的。

共有1个答案

池麒
2023-03-14

根据这次Python 3.2提交的评论,我怀疑这是一次意外。

这个commit使赋值表达式能够进行testlist\u star\u expr生产(这允许进行未细化的解包),但让return语句进行testlist生产。我怀疑commit错过了这一点(可能还有其他地方,但我现在关注的是return\u stmt制作)。

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

如果你好奇的话,这就是我所做的改变。请随意克隆或下载我的叉子。

更新:我已经提交了一个bpo问题和一个退货(和产量)解包请求。

 类似资料:
  • 我在看stackoverflow的另一页时,遇到了一个循环排序的工作实现,但我不明白在while循环中,带分号的语句如何在大括号之前存在。我认为while循环应该完全终止,一旦找到带有分号的语句,就不会执行进一步的操作,那么大括号中的代码是如何执行的呢?乍一看,我会将其解释为“var”随着while循环的每次迭代而递增——但我知道情况并非如此,因为将其从该点移除并将“var”放在花括号内会导致无限

  • 问题内容: 函数内部的这两个语句之间有区别吗? 还有这个? 前者周围有括号。 问题答案: 从C 14开始,它们经常是。C 14增加了一种边缘情况,其中返回值周围的括号可能会改变语义。此代码段显示了要声明的两个函数。唯一的区别是在返回值两边加上括号。 在第一个中func1返回int,在第二个中func1返回int&。语义上的差异与周围的括号直接相关。 autoC 11中引入了最新形式的说明符。在C

  • 问题内容: 假设我们在Python 3.x中(我猜在Python 2.6和Python 2.7中也)具有以下功能: 如果运行它们,我们将得到: 这三个函数提供相同的结果(值和类型),它们似乎是等效的。 但是,其中哪个陈述更正确? 这些定义中是否有副作用? 相同的问题适用于以下情况,并返回了多个值: 在这种情况下,每个函数都返回一个 元组 ,但是我的问题仍然保持不变。 问题答案: Python中的括

  • 问题内容: 不知道这是否是Mozilla特定的JS语法,但是我经常发现以这种方式声明变量,例如,在附加SDK docs中: 并在各种Chrome Javascript中(使用代替的语句), 我发现这很令人困惑,但即使在MDN上,我也找不到有关这两种语法的任何文档。 问题答案: 它们都是JavaScript 1.7的功能。第一个是block-level variables: : 允许您声明变量,将其

  • 这里我理解哈希(#)符号将定义为本地模板变量,但是前面的星号是什么意思呢?还有,有必要吗? 下面是使用括号的示例: 我有点理解周围的括号将它绑定到HTML属性/Angular指令。这是否意味着它们是Angular计算表达式的指针?就像是Angular 1中的的等价物? 我猜真正的问题是,这些符号在Angular 2中有特殊的含义吗,知道何时使用每一个的最简单的方法是什么?谢谢!!

  • 问题内容: 我以为还会有另一个问题,但我找不到。在使用PHP的MySQL中,我通常用反引号封装字段名,以掩盖任何保留的名称或字符。但是,我的一位同事指出,这也可以使用方括号来实现。排除反引号与SQL Server不兼容的事实(显然),有什么区别?我应该使用哪个? 问题答案: SQL Server / T-SQL使用方括号(以及MS Access),而MySQL使用反引号。 据我所知,可以在文档中露