Search code examples
pythonunpackargument-unpacking

Python - value unpacking order in method parameters


def fun(a, b, c, d):
    print('a:', a, 'b:', b, 'c:', c, 'd:', d)

why this one works

fun(3, 7, d=10, *(23,))

and prints out:

a: 3 b: 7 c: 23 d: 10

while this

fun(3, 7, c=10, *(23,))

does not

Traceback (most recent call last):
  File "/home/lookash/PycharmProjects/PythonLearning/learning.py", line 10, in <module>
    fun(3, 7, c=10, *(23,))
TypeError: fun() got multiple values for argument 'c'

Solution

  • With *(23,), you are unpacking the values in the tuple (23,) as positional arguments, following the positional arguments that are already defined, namely 3 for a and 7 for b, so 23 would be assigned to parameter c, which is why fun(3, 7, d=10, *(23,)) works, but in fun(3, 7, c=10, *(23,)) you are also assigning to value 10 to c as a keyword argument, so it is considered a conflict as c cannot be assigned with both 23 and 10.

    Note that while legal, it is discouraged by some to unpack iterable arguments after keyword arguments, as discussed here, although the syntax is ultimately ruled to stay.