Python 3.5 TypeError: got multiple values ​​for argument

def f(a, b, *args): return (a, b, args) f(a=3, b=5) (3, 5, ()) 

while:

 f(a=3, b=5, *[1,2,3]) TypeError: got multiple values for argument 'b' 

Why is he acting like that?
Any specific reason?

+5
source share
2 answers

In the documentation for calls:

If the syntax *expression appears in a function call, the expression must be evaluated iterable. Elements from these iterations are treated as if they were additional positional arguments. To call f(x1, x2, *y, x3, x4) , if y is evaluated by the sequence y1, ..., yM , this is equivalent to calling with M+4 positional arguments x1, x2, y1, ..., yM, x3, x4 .

And this follows:

The 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).

(my emphasis)

So, Python first treats *args as positional arguments, assigns a value to b and reassigns it to b=5 , which results in an error for a keyword argument that has multiple values.

+5
source

The problem is the keywords. You are not allowed positional arguments after keyword arguments.

 f(3, 5, *[1,2,3]) 

works great as it passes a tuple with values ​​1,2,3. Same as:

 f(3, 5, *(1,2,3)) 

The keyword should always appear after positional arguments, therefore this declaration of your function 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)) 
0
source

All Articles