What are args and kwargs in Python?

July 20, 2021
Cover image for What are args and kwargs in Python?

You may encounter a situation where you would want to pass in as many positional arguments or keyword arguments to a function call as you want. This is where args and kwargs in Python come in handy. There may be instances where we want to make a function more flexible by allowing any number of arguments to be passed in.

*args

With *args, we can have as many positional arguments as we want. The datatype for *args is a tuple. For example, consider a function that prints out all its arguments:

The parameter name can be whatever we want. The important part is denoting the single asterisk. So, we could have also written:

def displayArgs(*args):
for arg in args:
print(arg)
displayArgs("These", "will", "all", "print")

We can also declare other parameters that will not be part of *args. In the example below, the first argument will be the message, and the remaining arguments will be in *args.

def displayArgs(message, *words):
print(f"Message: {message}")
for word in words:
print(word)
displayArgs("Printing out all the arguments that follow this message", "These",
"will", "all", "print")

**kwargs

With **kwargs, we can have as many keyword arguments as we want. The datatype for **kwargs is a dictionary. For example, consider a function that displays all test scores:

def displayTestResults(**kwargs):
total = 0
for test in kwargs:
print(f"For {test}, you scored {kwargs[test]}")
total += kwargs[test]
print(f"The total points you earned is {total}")
displayTestResults(test1=70, test2=80, test3=90)

As the same as *args, the parameter name can be whatever we want with **kwargs. Python distinguishes based on the number of asterisks. So with **kwargs, remember to use two asterisks. Using a different parameter name, we could have written this as:

def displayTestResults(**tests):
total = 0
for test in tests:
print(f"For {test}, you scored {tests[test]}")
total += tests[test]
print(f"The total points you earned is {total}")
displayTestResults(test1=70, test2=80, test3=90)

Just like with *args, there can be other parameters that will not be part of **kwargs. In the example below, the first argument will me a message, and the remaining keyword arguments will be in **kwargs.

def displayTestResults(message, **tests):
print(f"Message: {message}")
total = 0
for test in tests:
print(f"For {test}, you scored {tests[test]}")
total += tests[test]
print(f"The total points you earned is {total}")
displayTestResults("Printing test results", test1=70, test2=80, test3=90)

Combining args and kwargs in Python

We can go a step further and even use a combination of both args and kwargs in Python. Here's an example of a function that adds all the arguments first and then performs multiplication and division after if they are passed in (assuming we are expecting only numbers to be passed in as parameters):

def calculate(*args, **kwargs):
result = 0
for n in args:
result += n
if "multiply" in kwargs:
result *= kwargs.get("multiply")
if "divide" in kwargs:
result /= kwargs.get("divide")
print(result)
calculate(1, 2, 3, 4, 5, multiply=3, divide=2)