In this article, let’s learn about Python *args and **kwargs and its functionality. *args and **kwargs are often used as parameters in function definitions enabling us to pass multiple arguments to the function.
*args as a parameter in function definition allows you to pass a non-keyworded, variable-length tuple to the calling function. **kwargs as a parameter in function definition will enable you to pass keyworded, variable-length dictionary argument list to the calling function
There may be times when we don’t know the number of arguments a function may receive. In those cases, we cannot decide upon the number of arguments to use in the function definition.
For Example, If we are writing an addition program with two numbers like below.
def calculateSum(a, b): print ("Sum : ",a+b) calculateSum(10,20)
In the code above, we have built the calculateSum() function with ‘a’ and ‘b’ as arguments, and this code works well when the user who is using the function passes only two arguments.
If the user is not aware of the number of arguments that need to be passed and passes three arguments to our calculateSum() function, then our code fails and throws an error.
TypeError: calculateSum() takes 2 positional arguments but 3 were given
Python *args and **kwargs
If we want to develop a function which takes up ‘n’ arguments, then we need to use a variable-length argument in the function definition. A variable-length argument is an argument that accepts any number of arguments. Python *args and **kwargs are used solely for this purpose.
Python *args
In the above code, we are not sure how to pass variable length arguments to a function, and Python *args allows you to pass non-keyworded, variable length arguments to the function. We need to use a single asterisk(*) symbol before the argument to denote a non-keyworded, variable-length tuple argument.
We can write the above function like below.
def calculateSum(*args): total = 0; for arg in args: total += arg print("Sum is : ",total) calculateSum(10,20) calculateSum(10,20,30) calculateSum(10,20,30,40) calculateSum(10,20,30,40,50)
So, when we run the code, we will get output for all of the functions calls even though each one passes a different number of parameters.
Sum is : 30 Sum is : 60 Sum is : 100 Sum is : 150
Since we have used python *args, which accepts variable length arguments, the code executes successfully without any issues.
Python **kwargs
Python **kwargs is almost similar to Python *args instead of taking non-keyword arguments, and it takes a keyworded, variable-length dictionary argument. We must use double-asterisk(**) before the argument to denote the keyword variable-length dictionary argument.
First, let’s create a Python **kwargs function, which simply prints the elements of the kwargs
def sports(**kwargs): print(kwargs) sports(sport="Football", player="Zidane")
When we run the code, we will get output like below.
{'sport': 'Football', 'player': 'Zidane'}
For a better understanding, let’s write one more program, this time, we will iterate through the kwargs and get the individual key and value.
def userDetails(**kwargs): for key, value in kwargs.items(): print("Your {} is {}".format(key, value)) userDetails(name="John", country="India")
Upon execution, we will get the below output.
Your name is John Your country is India
Is it necessarily be *args and **kwargs?
Absolutely NO, only the asterisks before args and kwargs are mandatory; the variable name args and kwargs can be anything like *var1 and **var2, respectively. args and kwargs are just a popular convention.
For example,
def legends(*players): for player in players: print(player,end=" ") legends("Rossi", "Tyson", "Federer", "Zidane")
Let’s run the code now and check whether the code is working fine.
E:\Python>python legend.py Rossi Tyson Federer Zidane
Using *args and **kwargs together
We can use both *args and **kwargs together in a single function without any issues. To make it more interesting, we will add a standard argument as well.
def display(msg, *fruits, **player): print(msg) for fruit in fruits: print(fruit, end=" ") print() for key, value in player.items(): print("{} is {}".format(key,value))
In the above code, msg acts as a positional argument, *fruits is our *args and **players acts as **kwargs
Upon execution, we will get the output as
>>> display("Welcome", "Apple", "Orange", name="Zidane", sports = "football") Welcome Apple Orange name is Zidane sports is football
Note: We CANNOT shift the position of *args and **kwargs, args should come before kwargs. In the above code if I am moving the positions of **player and *fruits like below
def display(msg, **player, *fruits): print(msg) for fruit in fruits: print(fruit, end=" ") print() for key, value in player.items(): print("{} is {}".format(key,value))
The code will throw Invalid Syntax Error
File "disp.py", line 1 def display(msg, **player,*fruits ): ^ SyntaxError: invalid syntax
Just remember this order of arguments to a function
- Positional Argument
- *args
- **kwargs
Using *args and **kwargs in function calls
We all know by *args is a tuple, and **kwargs is a dictionary. Why can we use it in a function call?
Let’s start with *args in a function call.
def eatables(fruit1, fruit2, fruit3): print("Fruit1 : ",fruit1) print("Fruit2 : ",fruit2) print("Fruit3 : ",fruit3)
In the above code, we have created a function that takes three arguments and prints each of them.
Create a tuple fruits and pass it to our function eatables
>>> fruits = ("Apple", "Orange", "Banana") >>> eatables (*fruits) Fruit1 : Apple Fruit2 : Orange Fruit3 : Banana
To call the above function we don’t necessarily use a tuple alone, we can use a list also. Let’s try that as well.
>>> fruit_list = ["Apple", "Orange", "Banana"] >>> eatables (*fruit_list) Fruit1 : Apple Fruit2 : Orange Fruit3 : Banana
Similarly, let’s re-use the same function and create a matching **kwargs, and call.
All we need to do is, the key of kwargs should be matching the argument (fruit1, fruit2, fruit3) of the function, like below
>>> fruit_kwargs = {"fruit1" : "Apple", "fruit2" : "Orange", "fruit3" : "Banana"} >>> eatables (**fruit_kwargs ) Fruit1 : Apple Fruit2 : Orange Fruit3 : Banana
Happy Learning!!
Leave a Reply