1

The issue here is I want to pass a tuple as an argument to a second function. Before there are outcries of "duplicate!" I have already looked at a post regarding a similar question Expanding tuples into arguments

Here is the code I am testing with:

def producer():
    return ('a','b')

def consumer(first, second, third):
    print first+second+third

arg = producer()
consumer(*arg, 'c') # expected abc

This outputs the error:

There's an error in your program *** only named arguments may follow *expression

This useful error message has led switch the order of arguments to consumer('c', *arg), but this does not quite solve the issue as it will output 'cab'.

So my question is, is there a better way to pass in a tuple to a multi argument function, and preserve the ordering?

Also for bonus points, what does the '*' operator do? (this was not explained in the previous post)

Community
  • 1
  • 1
The2ndSon
  • 307
  • 2
  • 7
  • See [What does \*\* (double star) and \* (star) do for Python parameters?](http://stackoverflow.com/q/36901) about what `*` does. It is **not** an operator. – Martijn Pieters Jul 10 '14 at 21:19
  • While it's not legal now, the draft [PEP 448](http://legacy.python.org/dev/peps/pep-0448/) proposes to make `func(*args, arg)` and many other unpacking variations legal in some future Python version. See also [issue 2292](http://bugs.python.org/issue2292) which discusses attempts at implementing this behavior. Alas, there doesn't seem to have been much progress in the last year or so. – Blckknght Jul 10 '14 at 22:05

2 Answers2

6

As the error message states, Python does not allow you to have unnamed arguments after *arg.

Therefore, you need to explicitly name third:

>>> def producer():
...    return ('a','b')
...
>>> def consumer(first, second, third):
...    print first+second+third
...
>>> arg = producer()
>>> consumer(*arg, third='c')
abc
>>>
1

If you need to add an argument, concatenate the tuple:

arg += ('c',)
consumer(*arg)

Alternatively, you can name the argument explicitly by using a keyword parameter:

consumer(third='c', *arg)

You cannot put more positional arguments after *arg, these are always added to any explicit positional arguments.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343