How to define method with optional argument and argument unpacking?
-
21-06-2021 - |
Question
I have a question regarding how to define and call a method with both optional arguments and with a *args parameter in Python. For example,
def test_func(arg1, optional_arg=None, *args):
...
And I want to be able to call the method with either of the following statements:
test_func("foo", arg1, arg2, ..., optional_arg="bar")
...
test_func("foo", arg1, arg2, ...)
# arg1, arg2 ... belongs to *args;
# optional_arg is unset (defaults to None)
Is this possible at all, or do I always have to set optional_arg to something when calling a method like this? I.e. I only want optional_arg to be set when I specifically write optional_arg=... when calling the function.
Solution
You should use **kwargs for that.
def test_func(arg1, *args, **kwargs):
optional_arg = kwargs.get('optional_arg')
...
The only limitation is that the keyworded argument (optional_arg) must always be after keywordless arguments
>>> test_func("foo", optional_arg="bar", arg1, arg2, ...)
File "<stdin>", line 1
SyntaxError: non-keyword arg after keyword arg
>>> test_func("foo", arg1, arg2, ..., optional_arg="bar")
...
>>> test_func("foo", arg1, arg2, ...)
...
OTHER TIPS
Unfortunately the positional arguments force you to specify a value for the named argument even if it has a default value; you cannot get around this.
In Python, the keyword arguments must come last in a function call, you can't call test_func
as you did in your first example, optional_arg="bar" must come after all non-keyword arguments.
You could try this kind of workaround:
def test_func(arg1, *args,**optional_arg):
print arg1
print args
if 'optional_arg' in optional_arg:
print optional_arg['optional_arg']
test_func("foo", 'v','n',optional_arg="bar")
test_func("foo",'v','n')