DEV Community

Micheal Ojemoron
Micheal Ojemoron

Posted on

What does this mean in Python: *args, **kwargs?

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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

Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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

Enter fullscreen mode Exit fullscreen mode

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']
Enter fullscreen mode Exit fullscreen mode

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)

Collapse
 
swiknaba profile image
Lud

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 :-)

Collapse
 
rudolfolah profile image
Rudolf Olah

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.

Collapse
 
mburszley profile image
Maximilian Burszley

I mean, they're basically the same thing. Just two different styles.

Collapse
 
mojemoron profile image
Micheal Ojemoron • Edited

Thanks for the feedback

Collapse
 
lewiskori profile image
Lewis kori

Great post and well explained!

Collapse
 
mojemoron profile image
Micheal Ojemoron

Thanks for the feedback