函数调用和*表达式

时间:2014-08-27 10:27:08

标签: python python-3.x

我对funcion头中的参数规则和函数调用中的参数规则有点混淆。

这是我的疑惑点:

根据文件:

  

如果语法*表达式出现在函数调用中,则表达式必须求值为iterable。来自此迭代的元素被视为它们是附加的位置参数;如果存在位置参数x1,...,xN,并且表达式求值为序列y1,...,yM,则这相当于具有M + N个位置参数x1,...,xN,y1,...的调用。 ..,yM。

所以如果有这样的函数:

def func(a, *b): ....

为什么我不能这样做:

func(1, *[2, 3], *[4, 5])

这不等于x1,...,xN,y1,...,yN,w1,...,wN? 为什么这不起作用?

3 个答案:

答案 0 :(得分:4)

首先,不要因为*args可以在函数声明和函数调用中使用而感到困惑。虽然这两者是松散相关的,但它们并不是一回事。您可以使用foo(*args)调用函数,而不使用可变数量的参数声明它,并且无需使用解压缩的可迭代函数调用使用def foo(*args)定义的函数。

您看到的真正问题是在函数调用中只允许一个*args解包。这就是Python语法的指定方式。但是,这可能会在将来发生变化,因为PEP 448会寻求对解包语法进行概括,以便可以在更多情况下使用它。如果PEP获得批准并实施,则foo(*args, *args2)等函数调用将合法化。

答案 1 :(得分:3)

首先,与函数签名无关。 调用语法函数定义是碰巧使用*来表示相关事物的两个独立概念。 f()的定义在这里无关紧要。

Calls expressions documentation中定义的语法不允许多个*expression*部分:

argument_list        ::=  positional_arguments ["," keyword_arguments]
                            ["," "*" expression] ["," keyword_arguments]
                            ["," "**" expression]
                          | keyword_arguments ["," "*" expression]
                            ["," keyword_arguments] ["," "**" expression]
                          | "*" expression ["," keyword_arguments] ["," "**" expression]
                          | "**" expression

每个|都是替代部分,每个[...]都是可选的。这些都不允许*expression出现多次。

请注意,Python 2 rendering of the documentation中存在错误,其中

| "*" expression ["," keyword_arguments] ["," "**" expression]

已被错误的

取代
| "*" expression ["," "*" expression] ["," "**" expression]

issue #22288(文档有been fixed)。

未来的Python版本可能放宽此限制。见PEP 448 - Additional Unpacking Generalizations;这只适用于Python的未来版本,最早是Python 3.5。

答案 2 :(得分:0)

因为语法不允许它。

您可以使用以下内容来达到相同的效果:

func(1, *([2, 3] + [4, 5]))