Python中奇怪的语法解析错误?
我是不是漏掉了什么?为什么“坏掉”的那部分代码不应该工作?我在用Python 2.6。
#!/usr/bin/env python
def func(a,b,c):
print a,b,c
#Working: Example #1:
p={'c':3}
func(1,
b=2,
c=3,
)
#Working: Example #2:
func(1,
b=2,
**p)
#Broken: Example #3:
func(1,
b=2,
**p,
)
2 个回答
5
在Python中,通常在用逗号分隔的列表的最后,可以多加一个逗号,比如在参数列表和容器字面量中。这样做的主要目的是为了让代码生成变得稍微简单一些(你不需要特别处理最后一个项目,或者处理只有一个元素的元组)。
在语法定义中,**kwargs
是单独提出来的,而且不需要额外的可选逗号。就我所能想象的,它在实际应用中对代码生成没有什么帮助(因为**kwargs
总是最后一个,所以你不需要特别处理任何东西),所以我不明白为什么Python会支持这个。
9
这里是来自语法的相关内容:
arglist: (argument ',')* (argument [',']
|'*' test (',' argument)* [',' '**' test]
|'**' test)
这里的第一行允许在最后一个参数后面加一个逗号,前提是你没有使用可变参数(varargs)或关键字参数(kwargs),这就是为什么你的第一个例子可以工作的原因。不过,如果你指定了kwargs参数,就不允许在它后面加逗号,这在第二行和第三行中有说明。
顺便提一下,这里有一个有趣的点是语法中展示的:
这两种写法都是合法的:
f(a=1, b=2, c=3,)
f(*v, a=1, b=2, c=3)
但这个就不合法:
f(*v, a=1, b=2, c=3,)
不允许在**kwargs
后面加逗号是有道理的,因为它必须始终是最后一个参数。不过,我不太明白为什么语言设计者选择不允许我的最后一个例子,可能是个疏忽吧?