*args and **kwargs in Python

*args and **kwargs in Python

Introduction

You might find yourself writing functions in Python that require many arguments, and this can be tiring at times. Let’s say that you want to write a function to add ten numbers. You would have to specify ten different parameters! That isn't fun at all.

Fortunately, Python has an easy way of solving this problem, which involves using arbitrary arguments. To pass a variable number of arguments to a function, you can use *args (non-keyword arguments) or **kwargs (keyword arguments). *args and **kwargs are both prefixed by the unpacking operator, which is an asterisk (*). Unpacking operators allow values to be unpacked from iterable objects such as lists, tuples, and dictionaries.

This article will teach you about *args and **kwargs and how to apply them when writing Python code.

What is Python *args?

This allows you to pass a variable number of non-keyword arguments, which are assigned based on the position of the parameters. When creating *args, the asterisk must not be omitted, or else the code will not work as expected.

When you use *args, the arguments get packed into a tuple, which can be accessed from within a function. Certain operations can be performed with *args, which will be discussed below.

Using *args in a Function

To pass a variable number of non-keyword arguments, you can simply apply *args, as shown in the code below:

def add(*args):
    total = 0
    for arg in args:
        total += arg
    return total
print(add(1,2,3,4,5,6,7,8))

Output:

As shown in the code above, there was the add function, where *args was set as the parameter, and there was also a variable named total. After using the for loop to iterate over the args, each individual arg was added to the total variable. The total was then returned. Finally, after passing in the arguments, the function was called, and an answer was printed out.

Using an Extra Argument with *args

You can put an extra argument before *args in a function, and it will not be affected.

def add(value, *args):
    print(value)
    for arg in args:
        print(arg, end=" ")
add(20, 2, 3)

Output:

There were two print statements in the code above, one for the extra argument and one for the *args, where the ending character was replaced with a space. If necessary, you can use many arguments alongside *args.

Using *args to Set the Values of an Object

When you create a class that will serve as a blueprint for an object, you can use *args in its object constructor. It allows you to create many instance variables, which represent the attributes of the object.

class superhero():
    def __init__(self, *args):
        self.name= args[0]
        self.power= args[1]
batman= superhero("bruce", "money")
wolverine= superhero("logan", "immortality")

print(batman.name)
print(wolverine.power)

Output:

*args was accessed like a Python list, and its indexes were assigned to each instance variable in the constructor. This was followed by the creation of objects for the superhero class and, lastly, the printing out of the values of both objects.

What is Python **Kwargs?

Multiple keyword arguments can be passed using **kwargs. If you are unfamiliar with a keyword argument, it is an argument that shares the same name as the specified parameter in a function, while also taking a value. In a way, keyword arguments are similar to Python dictionaries. **kwargs, unlike *args, requires two asterisks and will not function if one of the asterisks is mistakenly omitted.

When you create **kwargs, the arguments get packed into a dictionary, unlike in *args, where they get packed into tuples. **kwargs can be accessed using dictionary methods, which will be discussed below.

Using **kwargs in a Function

**kwargs are easy to use, and they function like dictionaries. You can use the keys(), values(), and items() methods to iterate over **kwargs.

def details(**kwargs):
    for key, value in kwargs.items():
        print(f"{key} = {value}")
details(name="john", age=33)

Output:

In summary, **kwargs can be accessed like a Python dictionary. The keyword arguments use a key-value syntax, as shown in the code above, where "name" was the key and "john" was the value.

Using an Extra Argument with **kwargs

** kwargs, like *args, allows you to use an extra argument in a function.

def details(value, **kwargs):
    print(value)
    for key, value in kwargs.items():
        print(f"{key} = {value}")
details(20, name="john", age=33)

Output:

As you can see, the code had two print statements, one for the extra argument and one for the **kwargs.

Using **kwargs to Set the Values of an Object

**kwargs can also be used in a class’s object constructor. It allows you to create many instance variables that represent the attributes of the object. The attributes use the key-value syntax.

class superhero():
    def __init__(self, **kwargs):
        self.name= kwargs["n"]
        self.power= kwargs["p"]
batman= superhero(n="bruce", p="money")
wolverine= superhero(n="logan", p="immortality")

print(batman.name)
print(wolverine.power)

Output:

**kwargs assigned to the instance variables, indexes that contained letters, which served as keys for the values of the objects. This differentiates it from *args, which uses numerical indexes.

Using Both *args and **kwargs in a Single Function

You can use both *args and **kwargs in the same function. This allows you to use both non-keyword and keyword arguments simultaneously.

def combine(*args, **kwargs):
    print(args)
    print(kwargs)
combine("josh", "brolin", name="thanos", age=100)

Output:

In the combine function, *args was simply printed out. The keys and values of keyword arguments stored in the **kwargs were also printed out.

Conclusion

Python *args and **kwargs are easy to understand, but it requires practice before one can fully master them.