Can *args be used after a keyword argument

Viewed 73

I have a function which calls another function using a kwarg to determine if it should be called:

def a(val):
    print(val)

def caller(func, call_it=True, *args, **kwargs):
    if call_it:
        func(*args, **kwargs)

# doesnt work
caller(a, 1)

# works
caller(a, True, 1)

How can this be handled where the call_it argument has a default value but *args are still needed?

3 Answers

No, keyword arguments cannot precede normal arguments. A valid signature would be caller(func, *args, call_it=True, **kwargs).

No. A function signature looks like:

def funcname(req_positional, *args, named_keyword, named_keyword_with_default=None, **kwargs):
    # function body

You can sub some of those out if you don't need to reference them, for instance:

def funcname(a, b, c, *, must_be_a_keyword_argument):
    pass

>>> funcname(1, 2, 3, 4)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: funcname() takes 3 positional arguments but 4 were given
>>> funcname(1, 2, 3, must_be_a_keyword_argument=4)
>>>

See the official documentation for a more formal description

You need to change the function signature to

def caller(func, *args, call_it=True, **kwargs):
    ...
Related