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 the character names.
Example: function
that prints character names
def characters(name1, name2, name3):
print(name1, name2, name3)
characters("Iron Man", "Black Panther", "Captain America")
Output
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 of the extra argument passed inside the function, which only accepts three arguments.
That's unfortunate because we need to pass one more argument inside the function character
in order for the code to run without error.
However, this is not the best practice. For example, suppose you are working on a project where you need to add multiple arguments dynamically when calling a specific function.
What should you do in such situations? There is a way to deal with such situations.
Usage of *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 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 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 you want instead of args
, including your pet's name, a friend's name, or even your girlfriend's name, as long as you put a *
before it.
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 one exception: when passing regular arguments and *args
as parameters to a function, never pass *args
before regular arguments.
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")
Output
TypeError: heroes() missing 1 required keyword-only argument: 'country'
We got a TypeError
because we cannot pass *args
before the regular argument.
There will be no error if we change the code and move the parameters passed inside the function.
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 was executed without any error.
Usage of **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 the 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, we'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)
Output
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
You'll notice that the variables called names
and roles
in the above code were used.
However, we put *
before the names
variable and **
before the roles
variable when we passed them inside the function.
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 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.
🏆Other articles you might be interested in if you liked this one
✅Context managers and the with statement in Python.
✅Display local and web images in the Jupyter Notebook.
✅Public, Protected, and Private access modifiers in Python.
✅How to change the string representation of the objects using the str and repr method?
✅What is enumerate() function in Python?
✅Execute dynamically generated code using the exec() in Python.
✅Difference between the reverse() and the reversed() function in Python.
That's all for now
Keep Coding✌✌.
Top comments (5)
Excellent post! It's very simple and well explained!
Glad, you liked it
Awesome thanks
Thanks for the appreciation.
Excellent explanation. I didn't know about the unpacking operators, I was just used to see them but didn't fully understand them :)