Reputation: 588
I know that Python supports variable arguments *args
and keyword arguments **kwargs
but is there a way to have a default for these fields? If not, why?
*args = (1,'v')) , **kwargs = {'a':20}
I am not saying that I have a use case for this but it seems there is also no reason to disallow this. I do understand that it is trivial to get around this by checking for empty args
.
Upvotes: 0
Views: 1881
Reputation: 1122342
No, *args
and **kwargs
are the catch-all arguments that receive any arguments for which there are no explicit arguments instead. Specifying defaults defeats their purpose. Instead, your example defaults can be handled with existing syntax, there is no need to complicate the function definition syntax here.
You can cover your defaults by specifying normal keyword arguments:
def foo(pos0, pos1='v', a=20, *args, **kwargs):
pass
I replaced your (1, 'v')
'default' with another keyword argument, because you can provide values for keyword arguments with a positional parameter; foo(42, 'spam')
will set pos1
to 'spam'
.
In addition, you can always do further processing inside the function you define; the args
value is a tuple, just test for length to check if you need to use a default for missing values. kwargs
is a dictionary, just use kwargs.get(key, default)
or kwargs.pop(key, default)
or if key not in kwargs:
or any of the other dict
methods to handle missing keys.
Upvotes: 2
Reputation: 4265
You can have default kwargs
and still unpack with splat
a la **kwargs
def john(name, dog, *args, bob="bob", **kwargs):
print(name, dog, bob)
# "ream" is an unpacked arg
john("john", 1, "ream") # john 1 bob
# jane is an unpacked kwarg
john("john", 1, "ream", jane="jane") # john 1 bob
john("john", 1, "ream", bob="jane") # john 1 jane
Having a default for an *arg
is pretty difficult because the idea is to make the function require that input. You could look at some tricks in this vein a la the implementation for the range
builtin. I would just make it a kwarg
though.
Upvotes: 1