If you are new to python one stumbling block you will face during your learning experience is understanding the *args and **kwargs magical variables. I also had a hard time figuring how they work ๐
when I started.
def args_kwargs(*args, **kwargs):
pass
Python *args and **kwargs arguments are everywhere. You can find them in the source code of one of the most popular Python frameworks (Django).
The variable *args and **kwargs can be written in any form. e.g *vars and **kvars are also valid. Only the * (asterisk) is necessary.
In this lesson, I will explain what they are and how to use them ๐.
Using *args in a function definition:
*args can be used in function definitions. They allow the user to call a function with a number of variable arguments. Variable here means that you do not know beforehand how many arguments that can be passed to your function by the user so in this case, you use the *args keywords. What *args allows you to do is take in more arguments than the number of formal arguments that you previously defined. Internally they are represented using tuple data structure.
Note that before the variable number of arguments, zero or more normal arguments may occur.
An interesting example for usage of *args:
def positions(first_arg, *args):
print(f"Type of *args is {type(args)}") #print type of args
print(f"first position arg:{first_arg}")
for arg in args:
print(f"another arg through *args: {arg}")
positions('first','second','third','forth')
#results
Type of *args is <class 'tuple'>
first position arg:first
another arg through *args: second
another arg through *args: third
another arg through *args: forth
Using **kwargs in a function definition:
The special syntax **kwargs in a function definition is used to pass a keyworded, variable-length argument list.
**kwargs allows you to pass keyworded variable length of arguments to a function. Internally, they are represented using dictionary data structure.
Here is a basic example to explain this concept:
def items(**kwargs):
print(f"Type of **kwargs is {type(kwargs)}") #print type of **kwargs
#iterating over the keyword argument
if kwargs is not None:
for key, value in kwargs.items():
print(f"{key} = {value}")
items(a="basket", b="plate", c="soap")
#results
Type of **kwargs is <class 'dict'>
a = basket
b = plate
c = soap
From the above examples, we can see that using *args and *kwargs gives our function definitions the flexibility of accepting an unlimited number of arguments.
Let's look at some examples of using **args** and **kwargs when calling a function.
*args can be used to unpack values from iterable objects(list, tuple) in Python.
def test_args_kwargs(arg1,arg2,arg3):
print(f"{arg1},{arg2},{arg3}")
#using tuple
test_args_kwargs(*('first','second','third'))
#OR
test_args_kwargs(*['first','second','third'])
#results
first,second,third #unpacking tuple
first,second,third #unpacking list
While the **kwargs can only be used to unpack a dictionary.
# now with **kwargs:
kwargs = {"arg1": "first", "arg2": "second","arg3":"third"}
test_args_kwargs(**kwargs)
#results
arg1: first
arg2: second
arg3: third
Order of using *args **kwargs and formal args
The correct order for your parameters is:
standard arguments
*args arguments
**kwargs arguments
Let's see how to combine the various types of parameter:
#right
def my_func(args, *args, **kwargs):
pass
#wrong
def my_func(args, **kwargs, *args):
pass
Bonus
We can also use * to collect values during an assignment.
first,*others = ["first","second","third"]
print(first,others, sep="\n")
#results
first
['second', 'third']
I hope you now have a clear understanding of how to use *args and **kwargs when defining or calling a function in Python.
If you have any questions, please leave your comments below.
Next week, I will explain how to use Multithreading and Multiprocessing to speed up your programs :). Please follow me and turn on your notification. Thank you!
Happy coding! โ
Top comments (6)
For some it might be obvious, for some not. Here is the naming explained:
args: arguments
kwargs: keyword arguments
Also, this might be familiar, if you are learning Ruby, as it has the same syntax :-)
It's funny, but from much of the Ruby code I've seen in production code bases, most of them do not take advantage of keyword arguments. They still use the options hash style. With Python it seems much more idiomatic to use keyword arguments.
I mean, they're basically the same thing. Just two different styles.
Thanks for the feedback
Great post and well explained!
Thanks for the feedback