我对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? 为什么这不起作用?
答案 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]))