How To Use *args and **kwargs in Python 3

How To Use *args and **kwargs in Python 3

*args and **kwargs


I have come to see that most new python programmers have a hard time figuring out the *args and **kwargs magic variables. So what are they ? First of all let me tell you that it is not necessary to write *args or **kwargs. Only the * (asterisk) is necessary. You could have also written *var and **vars. Writing *args and **kwargs is just a convention.

The special syntax, *args and **kwargs in function definitions is used to pass a variable number of arguments to a function. The single asterisk form *args is used to pass a non-keyworded, variable-length argument list, and the double asterisk form is used to pass a keyworded, variable-length argument list. Here is an example of how to use the non-keyworded form. So now lets take a look at *args first.

Usage of *args


*args and **kwargs are mostly used in function definitions. *args and **kwargs allow you to pass a variable number of arguments to a function. What variable means here is that you do not know beforehand how many arguments can be passed to your function by the user so in this case you use these two keywords. *args is used to send a non-keyworded variable length argument list to the function. Here’s an example to help you get a clear idea:

Example 1

def test_var_args(f_arg, *argv):
    print("first normal arg:", f_arg)
    for arg in argv:
        print("another arg through *argv:", arg)

test_var_args('yasoob', 'python', 'eggs', 'test')

This produces the following result:

first normal arg: yasoob
another arg through *argv: python
another arg through *argv: eggs
another arg through *argv: test

Example 2

def multiply(*args):
    z = 1
    for num in args:
        z *= num
    print(z)

When we run this code, we’ll receive the product for each of these function calls:

>>> multiply(4, 5)
20
>>> multiply(10, 9)
90
>>> multiply(2, 3, 4)
24
>>> multiply(3, 5, 10, 6)
900
>>>
>>>
>>>
>>> mylist = [2, 3, 4, 5]
>>> multiply(*mylist)
120
>>> my_var = (2, 3, 4, 5)
>>> multiply(*my_var)
120

Because we used *args to send a variable-length argument list to our function, we were able to pass in as many arguments as we wished into the function calls.

With *args you can create more flexible code that accepts a varied amount of non-keyworded arguments within your function.

Understanding **kwargs


The double asterisk form of **kwargs is used to pass a keyworded, variable-length argument dictionary to a function. Again, the two asterisks (**) are the important element here, as the word kwargs is conventionally used, though not enforced by the language.

Like *args, **kwargs can take however many arguments you would like to supply to it. However, **kwargs differs from *args in that you will need to assign keywords.

First, let’s simply print out the **kwargs arguments that we pass to a function. We’ll create a short function to do this:

Example 1


def print_kwargs(**kwargs):
    print(kwargs)

output:

>>> print_kwargs(kwargs_1="Shark", kwargs_2=4.5, kwargs_3=True)
{'kwargs_1': 'Shark', 'kwargs_2': 4.5, 'kwargs_3': True}
>>>
>>>
>>> my_dictionary = {'one': '1', 'two': '2', 'three': '3'}
>>> print_kwargs(**my_dictionary)
{'one': '1', 'two': '2', 'three': '3'}

Depending on the version of Python 3 you are currently using, the dictionary data type may be unordered. In Python 3.6 and above, you’ll receive the key-value pairs in order, but in earlier versions, the pairs will be output in a random order.

What is important to note is that a dictionary called kwargs is created and we can work with it just like we can work with other dictionaries.

Example 2


Let’s now pass additional arguments to the function to show that **kwargs will accept however many arguments you would like to include:

def print_values(**kwargs):
    for key, value in kwargs.items():
        print("The value of {} is {}".format(key, value))

When we run the program at this point, we’ll receive the following output, which may be unordered:

# python3
Python 3.5.3 (default, Jan 19 2017, 14:11:04) 
[GCC 6.3.0 20170118] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> print_values(
...             name_1="Alex",
...             name_2="Gray",
...             name_3="Harper",
...             name_4="Phoenix",
...             name_5="Remy",
...             name_6="Val"
...         )
The value of name_4 is Phoenix
The value of name_6 is Val
The value of name_5 is Remy
The value of name_1 is Alex
The value of name_2 is Gray
The value of name_3 is Harper

Using **kwargs provides us with flexibility to use keyword arguments in our program. When we use **kwargs as a parameter, we don’t need to know how many arguments we would eventually like to pass to a function.

Ordering Arguments


When ordering arguments within a function or function call, arguments need to occur in a particular order:

  • Formal positional arguments

  • *args

  • Keyword arguments

  • **kwargs

In practice, when working with explicit positional parameters along with *args and **kwargs, your function would look like this:

def example(arg_1, arg_2, *args, **kwargs):
...

And, when working with positional parameters along with named keyword parameters in addition to *args and **kwargs, your function would look like this:

def example2(arg_1, arg_2, *args, kw_1="shark", kw_2="blobfish", **kwargs):
...

It is important to keep the order of arguments in mind when creating functions so that you do not receive a syntax error in your Python code.