问题
def f(a, b, *args):
return (a, b, args)
f(a=3, b=5)
(3, 5, ())
whereas:
f(a=3, b=5, *[1,2,3])
TypeError: got multiple values for argument 'b'
Why it behaves like this?
Any particular reason?
回答1:
In the documentation for calls:
If the syntax
*expression
appears in the function call, expression must evaluate to an iterable. Elements from these iterables are treated as if they were additional positional arguments. For the callf(x1, x2, *y, x3, x4)
, ify
evaluates to a sequencey1, ..., yM
, this is equivalent to a call withM+4
positional argumentsx1, x2, y1, ..., yM, x3, x4
.
And, this is followed by:
A consequence of this is that although the
*expression
syntax may appear after explicit keyword arguments, it is processed before the keyword arguments (and any**expression arguments
– see below).
(emphasis mine)
So Python will first process the *args
as positional arguments, assign a value to b
and re-assign it with b=5
resulting in an error for the keyword argument having multiple values.
回答2:
The problem is the keywords. You are not allowed positional arguments after keyword arguments.
f(3, 5, *[1,2,3])
works fine, in that it passes a tuple with the values 1,2,3. The same as:
f(3, 5, *(1,2,3))
Keywords must always come after positional arguments, so it is your function declaration which is incorrect:
def f(*args, a, b):
return (a, b, args)
print(f(a=3, b=5))
print(f(*[1,2,3], a=3, b=5))
Gives:
(3, 5, ())
(3, 5, (1, 2, 3))
来源:https://stackoverflow.com/questions/38247720/python-3-5-typeerror-got-multiple-values-for-argument