Python 语法:函数参数中的 `for`

Python Syntax: `for` in function arguments

以下部分复制自 official, complete Python 3 grammar

arglist: argument (',' argument)*  [',']

argument: ( test [comp_for] |
            test ':=' test |
            test '=' test |
            '**' test |
            '*' test )

comp_iter: comp_for | comp_if
sync_comp_for: 'for' exprlist 'in' or_test [comp_iter]
comp_for: [ASYNC] sync_comp_for
comp_if: 'if' test_nocond [comp_iter]

arglist 用于将参数传递给函数调用或 class 定义的多个地方。

我对规则感到困惑 argument : test [comp_for]。由于 . for . in . 生成器已经是 test 的有效推导,这似乎意味着 for 作为函数参数具有特殊含义。

my_function(x for x in range(3))

然而,只是玩弄这个定义总是将它解释为由描述的语法创建的普通生成器对象。

y = (x for x in range(3))
my_function(y)

那么,该语法实际上有什么特别之处吗?还是只是遗留/未来保留代码?

(x for x in range(3)) 是一个生成器表达式,它派生自 test 非终结符。但是 x for x in range(3) 不是从 test 派生的;括号是必要的。因此,如果没有 argument : test [comp_for] 产生式,sum((x for x in range(3))) 将是一个有效的函数调用,而不是 sum(x for x in range(3))

另一方面,sum(x for x in range(3)) 无法以任何其他方式解析,而且语法似乎没有带有额外括号的版本那么混乱。因此,当在 Python 2.4 中引入生成器表达式时,修改了参数列表的语法以使语法糖成为可能——但仅当生成器表达式是唯一的参数时。

您可以在 PEP 289 中找到更详细的更改说明。