I'm a bit confused about using *args
.
I want to write a function that takes a variable number of arguments but can still use the advantage of defining a predefined value for a keyword argument.
But it's not possible to write a function like this:
def foo(*args, bar = "foo"):
print bar, args
It's just possible to write it like this:
def foo2(bar = "foo", *args):
print bar, args
But then I call foo2
and pass the first argument it overrides the default value for bar
!.
foo2("somevalue")
somevalue ()
Is where a way of doing this better ??
I know I could write it like this:
def foo(*args, **kwargs):
kwargs["bar"] = "foo"
but something like the first method definition (which yields a syntax error) is more intuitive from my point of view.
You would use kwargs
and do the assignment in the call not the definition:
def foo2(*args, **kwargs): # kwargs takes our key/values arguments
print args, kwargs
foo2(1, 2, 3, bar="foo") # bar is assigned to in call when using kwargs
Which gives:
(1, 2, 3) {'bar': 'foo'}
You could use get
to set foo
as a default for bar
like so:
def foo2(*args, **kwargs):
kwargs["bar"] = kwargs.get("bar", "foo") # if bar is not set use foo as val
print args, kwargs
foo2(1, 2, 3, bar="foo")
foo2(1, 2, 3, bar="notfoo")
foo2(1, 2, 3)
So that kwargs["bar"]
is always foo
unless explicitly changed:
(1, 2, 3) {'bar': 'foo'}
(1, 2, 3) {'bar': 'notboo'}
(1, 2, 3) {'bar': 'foo'}