(这完全在Python 3.5.2上)
在PEP 448的底部,我看到了:
函数调用中未括号的理解(例如
f(x for x in it)
)已经有效。
这很有趣。如果我定义以下函数:
def f(a, b, c):
return a + b + c
然后那句话让我想到f(thing for thing in [1, 2, 3]) == 6
。但实际上,我得到了:
>>> f(thing for thing in [1, 2, 3])
TypeError: f() missing 2 required positional arguments: 'b' and 'c'
即。整个生成器表达式传递为a
。
那么PEP 448中的这句话是什么意思?只是你可以将生成器表达式作为参数传递?
答案 0 :(得分:4)
此声明仅表示在 pre-PEP 世界f(x for x in it)
中已经有效并将生成器表达式作为第一个函数参数传递。
要使您的示例正常工作,您需要显式解包生成器,如PEP示例中所示。
f(*(thing for thing in [1, 2, 3])) # returns 6
答案 1 :(得分:1)
Python允许您将单个生成器表达式传递给您正在调用的函数,而无需额外的括号。例如:
foo(x for x in range(10))
大致相当于:
genexp = (x for x in range(10)) # parentheses are necessary here
foo(genexp)
如果还有其他参数传递给函数调用(例如foo(w, (x for x in range(10)), y, z)
,那么在定义生成器表达式时仍然需要括号(其中第二个参数是{{1}的生成器表达式}}' S)
PEP顺便提一下,在这种情况下,解包语法的进一步扩展可能会令人困惑。如果一种新的生成器表达式x
是合法的(它不是最终的PEP的一部分,但正在考虑一段时间),那么(*x for x in nested)
应该如何工作?它是否等同于foo(*x for x in nested)
(使用单个生成器表达式调用,包括新的"展平" foo((*x for x in nested))
),或者它是否意味着*
(这是合法的)现在)?
答案 2 :(得分:0)
发生的事情是,在f(thing for thing in [1, 2, 3])
行,您只传递第一个参数,即一个生成器。缺少参数b
和c
。
另外,请检查PEP的以下部分:
但是,目前尚不清楚这是最好的行为还是它 应解压缩到f调用的参数中。既然如此 这可能是令人困惑的,并且只是非常边际的效用,事实并非如此 包含在本PEP中。相反,这些将抛出一个SyntaxError和 应该使用带有明确括号的理解。
答案 3 :(得分:0)
实际上f(x for x in it)
不是由PEP 448引入的新功能,而是由PEP 289引入的。注意到并非PEP 448中讨论的所有功能都在Python 3.5中实现。问题中提到的"Variations" section未实施:
因为这可能令人困惑,而且只是非常微不足道 实用程序,它不包含在本PEP中。相反,这些将抛出一个 应使用
SyntaxError
和带有明确括号的理解 代替。