Understanding *args & **kwargs in Python
When we see the documentation of any function that contains *args and **kwargs, have you ever wondered — What are these strange parameters passed inside that function?
As an example:
function(params, *args, **kwargs)
As a beginner, you might get confused about how to use that function or what to pass as an argument in place of * args and ** kwargs when calling that function.
Well not to worry, in this tutorial we gonna discuss *args
and **kwargs
- What they mean and their uses in the function with examples that help you to understand better.
And we gonna see the glimpse of *
and **
(Unpacking operators) used in the examples.
Introduction
The function in Python helps us to write code that is reused, to perform particular tasks in various operations.
Let’s define a function that prints character names:
Example: function
that prints character names
def characters(name1, name2, name3):
print(name1, name2, name3)
characters("Iron Man", "Black Panther", "Captain America")
If we run the program, the output would be
Iron Man Black Panther Captain America
The function " characters "
above takes 3 positional arguments "name1"
, "name2"
, "name3"
and simply prints the names.
What if we pass more than the number of arguments that it takes
def characters(name1, name2, name3):
print(name1, name2, name3)
characters("Iron Man", "Black Panther", "Captain America", "Hulk")
What do you think the output would be, the output will be a TypeError
TypeError: characters() takes 3 positional arguments but 4 were given
The error was raised because the function won’t be able to handle the intensity of the Incredible Hulk, I wish I could say that but, the error was raised due to the extra argument passed inside the function that takes only 3 arguments
That is sad because we need to pass one more argument inside the function character
to execute code without any error.
But this is not the best practice, suppose you are working on a project where you need to add multiple arguments dynamically when you are calling a particular function.
What to do in such cases? There’s a way to tackle such situations…
Usage of Python *args
*args
is simply shortened for arguments. It is used as an argument when we are not sure how many arguments should we pass in the function
.
The *
asterisk before the args
ensures that the argument has a variable length.
*args
is a Non-keyword argument or a Positional argument.
By using *args
, you are allowed to pass any number of arguments when calling a function.
Example: Using *args
in function definition
def friends(*args):
print(args)
friends("Sachin", "Rishu", "Yashwant", "Abhishek")
Output
('Sachin', 'Rishu', 'Yashwant', 'Abhishek')
We got our output as Tuple
because when we use *args
the function will get the arguments as Tuple
If we check the type
:
def friends(*args):
print(type(args))
print(args)
friends("Sachin", "Rishu", "Yashwant", "Abhishek")
Output
<class 'tuple'>
('Sachin', 'Rishu', 'Yashwant', 'Abhishek')
We can also use regular arguments with *args
Example: Using regular arguments and args in the function definition
def friends(greet, *args):
for friend in args:
print(f"{greet} to Python, {friend}")
greet = "Welcome"
friends(greet, "Sachin", "Rishu", "Yashwant", "Abhishek")
Output
Welcome to Python, Sachin
Welcome to Python, Rishu
Welcome to Python, Yashwant
Welcome to Python, Abhishek
Note: You can use any name, whatever it may be it could be your pet’s name, friend’s name even your girlfriend’s name instead of args
but make sure you put *
asterisk before that name.
Example: Using a different name instead of args
def dog(prefix, *german_shepherd):
for breed in german_shepherd:
print(f"The {prefix} is {breed}.")
prefix = "breed"
dog(prefix, "Labrador", "GSD", "Chihuahua")
Output
The breed is Labrador.
The breed is GSD.
The breed is Chihuahua.
There is an exception — When you pass regular argument and *args
inside the function together as a parameter, never pass *args
before regular argument.
Example: Using *args
before regular argument inside the function
def heroes(*characters, country):
for character in characters:
print(f"{character} is from {country}.")
country = "USA"
heroes(country, "Iron Man", "Captain America", "Spiderman")
What do you think the output would be
TypeError: heroes() missing 1 required keyword-only argument: 'country'
The output will be a TypeError
because we cannot pass *args
before the regular argument.
If we modify the code and change the position of parameters passed inside the function then there will be no error
def heroes(country, *characters):
for character in characters:
print(f"{character} is from {country}.")
country = "USA"
heroes(country, "Iron Man", "Captain America", "Spiderman")
Output
Iron Man is from USA.
Captain America is from USA.
Spiderman is from USA.
The above code is executed without any error.
Usage of Python **kwargs
**kwargs
is shortened for Keyword argument.
Now you are familiar with *args
and know its implementation, **kwargs
works similarly as *args.
But unlike *args
, **kwargs
takes keyword or named arguments.
In **kwargs
, we use **
double asterisk that allows us to pass through keyword arguments.
Example: Using **kwargs
in the function definition
def hello(**kwargs):
print(type(kwargs))
for key, value in kwargs.items():
print(f"{key} is {value}.")
hello(One = "Red", two = "Green", three = "Blue")
Output
<class 'dict'>
One is Red.
two is Green.
three is Blue.
The type
of **kwargs
is Dictionary i.e., the arguments accepted as key-value
.
Example: Using regular argument and **kwargs
together inside a function definition
def hello(write, **kwargs):
print(write)
for key, value in kwargs.items():
print(f"{key} is {value}.")
write = "RGB stands for:"
hello(write, One = "Red", two = "Green", three = "Blue")
Output
RGB stands for:
One is Red.
two is Green.
three is Blue.
Just like *args
, you can choose any name instead of **kwargs
Example: Using a different name instead of kwargs
def hello(write, **color):
print(write)
for key, value in color.items():
print(f"{key} is {value}.")
write = "RGB stand for:"
hello(write, One = "Red", two = "Green", three = "Blue")
Output
RGB stand for:
One is Red.
two is Green.
three is Blue.
Note: We cannot pass **kwargs
before *args
in the function definition otherwise, we'll get a SyntaxError
.
The convention should be —
function(params, *args, **kwargs)
Example
We can use all three types of arguments inside the function definition and in this example, you’ll see the use of the unpacking operator — *
and **
.
def friends(greet, *args, **kwargs):
for names in args:
print(f"{greet} to the Programming zone {names}")
print("\nI am Veronica and I would like to announce your roles:")
for key, value in kwargs.items():
print(f"{key} is a {value}")
greet = "Welcome"
names = ["Sachin", "Rishu", "Yashwant", "Abhishek"]
roles = {"Sachin":"Chief Instructor", "Rishu":"Engineer",
"Yashwant":"Lab Technician", "Abhishek":"Marketing Manager"}
friends(greet, *names, **roles)
The output would be
Welcome to the Programming zone Sachin
Welcome to the Programming zone Rishu
Welcome to the Programming zone Yashwant
Welcome to the Programming zone Abhishek
I am Veronica and I would like to announce your roles:
Sachin is a Chief Instructor
Rishu is a Engineer
Yashwant is a Lab Technician
Abhishek is a Marketing Manager
In the above code snippet, you can notice that I created variables named names
and roles
.
But when I call them in a function, I used *
before the names
variable and **
before the roles
variable.
These are the Unpacking operators.
Unpacking Operator
These operators come quite in handy as you saw above.
*
single asterisk is used to unpack iterable and **
double asterisk is used to unpack a dictionary.
The
*
iterable unpacking operator and**
dictionary unpacking operators to allow unpacking in more positions, an arbitrary number of times, and in additional circumstances. Specifically, in function calls, in comprehensions and generator expressions, and in displays. Source
To know more, click here
Conclusion
So far you will now be able to implement the fundamentals of *args
and **kwargs
inside the functions.
These might come in handy when you are working on projects where data comes dynamically in a function and you don’t know how many arguments to be passed in that function. This makes your project scalable.
That’s all for now
Keep Coding✌✌.
Originally published at https://geekpython.in.