In Python, both *args
and **kwargs
are special parameters that allow you to pass a variable number of arguments or keyword arguments to a function. The difference is that *args
collects the extra positional arguments as a tuple, while **kwargs
collects the extra keyword arguments as a dictionary. They can make your functions more flexible and adaptable to different situations.
You use *args
and **kwargs
when you don’t know how many arguments or keyword arguments you will receive, or when you want to pass along the arguments from one function to another. You can also use them to define generic functions that can handle different types of inputs.
Using *args
to collect an indefinite number of positional arguments (without keywords) as a tuple:
def foo(*args):
for arg in args:
print(arg)
foo(1, 2, 3, "four")
# Output:
# 1
# 2
# 3
# four
Using **kwargs
to collect an indefinite number of keyword arguments (with keywords) as a dictionary:
def foo(**kwargs):
for key, value in kwargs.items():
print(f"{key}: {value}")
foo(name="John", age=25, city="New York")
# Output:
# name: John
# age: 25
# city: New York
Using both *args
and **kwargs
in the same function definition to accept any combination of positional and keyword arguments. When combined, *args
always comes before **kwargs
.
def foo(arg1, *args, kwarg1="default", **kwargs):
print(f"arg1: {arg1}")
print(f"args: {args}")
print(f"kwarg1: {kwarg1}")
print(f"kwargs: {kwargs}")
foo(1, 2, 3, kwarg1="custom", name="John", age=25)
# Output:
# arg1: 1
# args: (2, 3)
# kwarg1: custom
# kwargs: {'name': 'John', 'age': 25}
While args
and kwargs
are conventional names and widely used for the purpose of clarity and readability, you are free to use any name of your choice. The key lies in the use of the *
and **
syntax, not the names themselves.