In python, can you pass variadic arguments after named parameters?

Question:

Is it possible to call instance methods in python 2.7 using both named and variadic arguments? I like to name parameters for clearer reading of code, but it seems like this code then fails:

def function(bob, sally, *args):
    pass

values = [1, 2, 3, 4]

function(bob="Hi bob", sally="Hello sally", *values)

raises:

TypeError: function() got multiple values for argument 'bob'
Asked By: JustinHK

||

Answers:

Yes, but with a slight modification to what you are doing:

def foo(bob="abc", sally="def", **kwargs):
    pass

foo(bob="stuff", sally="buff", other_stuff=[1, 2, 3])
Answered By: idjaw

can you pass variadic arguments after named parameters?

Python 3.4.3: the answer is yes.

You must place the variadic ones first in the function definition

def function(*args, bob, sally):
    print(args, bob, sally)

values = [1, 2, 3, 4]

function(bob="Hi bob", sally="Hello sally", *values)
function(bob="Hi bob", *values, sally="Hello sally")
function(*values, bob="Hi bob", sally="Hello sally")

produces

(1, 2, 3, 4) Hi bob Hello sally
(1, 2, 3, 4) Hi bob Hello sally
(1, 2, 3, 4) Hi bob Hello sally

As you can see, you can call the function placing the parameters in any order you prefer.

Please note:

the first and second calls above work only if you pass the positional arguments via the values iterable, unpacking its contents.

Passing each positional parameter

function(bob="Hi bob", sally="Hello sally", 1, 2, 3, 4)
function(bob="Hi bob", 1, 2, 3, 4, sally="Hello sally")

isn’t acceptable and produces

SyntaxError: positional argument follows keyword argument

Furthermore, since you explicitly refer to instance methods, it’s worth checking what happens if function is such a method, say of class A

class A():
    def function(self, *args, bob, sally):
        print(args, bob, sally)

values = [1, 2, 3, 4]
a=A()
a.function(bob="Hi bob", sally="Hello sally", *values)
a.function(*values, bob="Hi bob", sally="Hello sally")
a.function(bob="Hi bob", *values, sally="Hello sally")

still works and produces

(1, 2, 3, 4) Hi bob Hello sally
(1, 2, 3, 4) Hi bob Hello sally
(1, 2, 3, 4) Hi bob Hello sally

Python 2.7.6: the answer is no.

>>> def function(*args, bob, sally):
  File "<stdin>", line 1
    def function(*args, bob, sally):
                          ^
SyntaxError: invalid syntax

Another approach could be to give the variadic parameters a name as well

values = {'p1': 1, 'p2': 2, 'p3': 3, 'p4': 4}

then you could define

def function(bob, sally, **kwargs):
    print(kwargs['p1'])

and call it with

function(bob="Hi bob", sally="Hello sally", **values)
Answered By: Pynchia
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.