Variadic Arguments
I’m currently working on a challenge that needs to check for an arbitrary amount of arguments.
The Python docs have info on some so-called ‘variadic arguments’ which are what I seem to need to be using. The idea is to use these fancy *args
and **kwargs
arguments which then allow one to pass as many positional or keyword arguments as desired and just handle them within the function when/if they are present. I’ve seen them before but I don’t think I really dug into them this far before to see how they work. Regarding *args
, the docs state:
These arguments will be wrapped up in a tuple
This means I can do such a thing as this defining a function with the *args
argument:
$ cat testfile.py
#!/usr/bin/python
def myFunction(*args):
for arg in args:
print(arg)
myFunction('a','b','c')
$ ./testfile.py
a
b
c
Now onto **kwargs
. Python docs say that **kwargs
gets assigned to a dictionary:
When a final formal parameter of the form
**name
is present, it receives a dictionary containing all keyword arguments except for those corresponding to a formal parameter. This may be combined with a formal parameter of the form*name
(described in the next subsection) which receives a tuple containing the positional arguments beyond the formal parameter list. (*name
must occur before**name
.)
Such as follows:
$ cat testfile.py
#!/usr/bin/python
def myFunction(*args,**kwargs):
for arg in args:
print(arg)
for key,value in kwargs.items():
print(f'key:{key}, value:{value}')
myFunction('a','b','c',d=1,e=2,f=3)
$ ./testfile.py
a
b
c
key:d, value:1
key:e, value:2
key:f, value:3
I found it really interesting that it’s not *args
or **kwargs
that is the magic (as stated in the snippet above, as it references *name
). It’s the amount of asterisks - *
or **
- that does the trick. Note I can throw whatever name in there that I like:
def myNonTraditionalFunction(*pies,**cakes):
for arg in pies:
print(arg)
for key,value in cakes.items():
print(f'key:{key}, value:{value}')
myFunction('z','y','x',w=6,v=5,u=4)
z
y
x
key:w, value:6
key:v, value:5
key:u, value:4
I like these, and moreso now that I can understand better what’s going on in some code next time I see them.
Takeaways:
- Variadic arguments are denoted by
*
or**
- positional variadic arguments are placed into a tuple
- keyword variadic arguments are placed into a dict
- The positioning does matter. Any required positional args must come before the
*
arg, and any required keyword args must come between*
and**
. Then finally**
can be entered.**
cannot be placed before*
.