Earlier we saw how to write functions in python and how to call them in our program. For those functions, the number of inputs or arguments were defined. They took fixed number of positional or keyword arguments or had a default value assigned to one or more of the arguments.
But how to handle situations where we want to write a function wherein we do not know how many arguments we are going to give.
In these conditions, the *args
and **kwargs
functionality is used.
We will first try to understand how each of these work.
*args
When we include *args
in the definition of a function, it means that we can give it any number of keyword arguments to it.
To understand how *args
work, we will make a function that concatenates any string
arguments given to it.
But let’s do it stepwise. We will first see in what form the *args
are interpreted inside the function. We will just make our first version of the function that prints out the data type
of the args
object.
def add_str(*args):
print(f'The "args" are read as {type(args)} type of object.')
add_str(2,3,4,5)
The "args" are read as <class 'tuple'> type of object.
We see above that the function combines all the positional arguments of the function under *args
as tuple. This gives us the method with which to use them. Now we will modify this function that would concatenate the strings. If a number
is present we will convert it to string
and then concatenate.
To do this:
- an empty string is created and each position argument is iterated over and added to the empty string.
- we will use
str()
function to convert any numerical in theargs
. str()
function does not have any effect when given a string object as argument. So there is no need to check thetype
of the element inarg
.- we will insert a
space
character after eacharg
added.
def add_str(*args):
res = ''
for arg in args:
res = res + str(arg) + ' '
return res
add_str('a', 'fg', 'htw', 'c', 4, 'g5', 68)
'a fg htw c 4 g5 68 '
In summary, the *args
arguments in a function is interpreted as a tuple
inside a functions. Each element of the tuple
is the postional argument given to the function.
Now we will see how the **kwargs
are interpreted in the python function.
**kwargs
Only keyword arguments can be passed under **kwargs
.
Python
def add_str2(**kwargs):
print(f'The "kwargs" are read as {type(kwargs)} type of object.')
add_str2(a=2, b=4, c='teak', d = 'wood')
The "kwargs" are read as <class 'dict'> type of object.
So, the **kwargs
are read as a dictionary
in contrast to a tuple
in case of *args
.
Now, let’s write a function that does the same thing of concatenating the number/strings given to the function.
def add_str2(**kwargs):
res = ''
for key in kwargs:
res = res + str(kwargs[key]) + ' '
return res
add_str2(a=2, b=4, c='teak', d = 'wood')
'2 4 teak wood '
*args
and **kwargs
can be used when a function can be given optional arguments.
For example, the pyplot.plot
function has following syntax for calling:
matplotlib.pyplot.plot(*args, scalex=True, scaley=True, data=None, **kwargs)
You can see that the function takes regular keyword arguments which have default values, the *args
and also **kwargs
.
One example of its usage is:
plot(x, y, 'go--', linewidth=2, markersize=12)
Here, you can see that:
- none of the regular keyword arguments is given while calling the function. So the default values for these keyword arguments will be taken by the function.
- the arguments
x
,y
andgo--
will be taken by the function under*args
. - the keyword arguments
linewidth
andmarkersize
will be taken under**kwargs
.
Reference: The matplotlib code was taken from its documentation page
Using exact names for *args
and **kwarg
not necessary
We can use any name for *args
and *kwargs
. The only important thing is the single asterisk (*
) or the double asterisk (**
).
Single (*
) as in *name
will stand for positional arguments *args
.
Double (**
) as in **name
will stand for the keyword arguments **kwargs
.