Default arguments with *args and **kwargs
Just put the default arguments before the *args
:
def foo(a, b=3, *args, **kwargs):
Now, b
will be explicitly set if you pass it as a keyword argument or the second positional argument.
Examples:
foo(x) # a=x, b=3, args=(), kwargs={}
foo(x, y) # a=x, b=y, args=(), kwargs={}
foo(x, b=y) # a=x, b=y, args=(), kwargs={}
foo(x, y, z, k) # a=x, b=y, args=(z, k), kwargs={}
foo(x, c=y, d=k) # a=x, b=3, args=(), kwargs={'c': y, 'd': k}
foo(x, c=y, b=z, d=k) # a=x, b=z, args=(), kwargs={'c': y, 'd': k}
Note that, in particular, foo(x, y, b=z)
doesn't work because b
is assigned by position in that case.
This code works in Python 3 too. Putting the default arg after *args
in Python 3 makes it a "keyword-only" argument that can only be specified by name, not by position. If you want a keyword-only argument in Python 2, you can use @mgilson's solution.
The syntax in the other question is python3.x only and specifies keyword only arguments. It doesn't work on python2.x.
For python2.x, I would pop
it out of kwargs:
def func(arg1, arg2, *args, **kwargs):
opt_arg = kwargs.pop('opt_arg', 'def_val')