def f(a, b, *args):
return (a, b, args)
f(a=3, b=5)
(3, 5, ())
然而:
f(a=3, b=5, *[1,2,3])
TypeError: got multiple values for argument 'b'
为什么表现如此?
有什么特别的原因吗?
答案 0 :(得分:5)
在文档for calls:
中如果函数调用中出现语法
*expression
,则表达式必须求值为iterable。来自这些迭代的元素被视为它们是附加的位置参数。对于调用f(x1, x2, *y, x3, x4)
,如果y
评估为序列y1, ..., yM
,则这相当于使用M+4
位置参数x1, x2, y1, ..., yM, x3, x4
的调用。
然后是:
这样做的结果是虽然
*expression
语法可能出现在显式关键字参数之后,但它会在处理关键字参数之前进行处理(以及任何{{ 1}} - 见下文)。
(强调我的)
因此,Python将首先将**expression arguments
作为位置参数进行处理,为*args
分配值并使用b
重新赋值,从而导致具有多个值的关键字参数出错。
答案 1 :(得分:0)
问题在于关键字。关键字参数后不允许使用位置参数。
f(3, 5, *[1,2,3])
工作正常,因为它传递的值为1,2,3的元组。同样如下:
f(3, 5, *(1,2,3))
关键字必须始终位于位置参数之后,因此您的函数声明不正确:
def f(*args, a, b):
return (a, b, args)
print(f(a=3, b=5))
print(f(*[1,2,3], a=3, b=5))
给出:
(3, 5, ())
(3, 5, (1, 2, 3))