Python > Core Python Basics > Functions > Variable Arguments (*args, **kwargs)
Understanding *args and **kwargs in Python
This snippet demonstrates how to use *args
and **kwargs
in Python functions. These features allow you to create functions that can accept a variable number of positional and keyword arguments, respectively. This makes your functions more flexible and reusable.
Basic Example with *args
The *args
syntax allows a function to accept any number of positional arguments. Inside the function, args
is a tuple containing all the positional arguments passed to the function. In this example, my_function
prints each argument it receives.
def my_function(*args):
for arg in args:
print(arg)
my_function('Hello', 'Python', 'World')
Basic Example with **kwargs
The **kwargs
syntax allows a function to accept any number of keyword arguments. Inside the function, kwargs
is a dictionary containing all the keyword arguments passed to the function. In this example, my_function
prints each key-value pair from the dictionary.
def my_function(**kwargs):
for key, value in kwargs.items():
print(f'{key}: {value}')
my_function(name='Alice', age=30, city='New York')
Combining *args and **kwargs
You can use both *args
and **kwargs
in the same function definition. *args
should always come before **kwargs
in the function signature. This example demonstrates how to access both positional and keyword arguments within the function.
def my_function(*args, **kwargs):
print('Positional arguments:')
for arg in args:
print(arg)
print('\nKeyword arguments:')
for key, value in kwargs.items():
print(f'{key}: {value}')
my_function('Hello', 123, name='Bob', age=25)
Concepts Behind *args and **kwargs
*args
and **kwargs
are powerful tools for creating flexible functions. They utilize the concepts of packing and unpacking arguments. *args
packs multiple positional arguments into a tuple, while **kwargs
packs multiple keyword arguments into a dictionary. This allows a function to handle varying numbers of inputs without explicitly defining each parameter.
Real-Life Use Case
A common use case for *args
and **kwargs
is when creating wrapper functions or decorators. These functions often need to pass along an arbitrary number of arguments to the original function being wrapped or decorated. They're also useful when dealing with API calls where the number of parameters might vary.
Best Practices
*positional_arguments
, **keyword_arguments
) to improve code readability.*args
and **kwargs
unnecessarily. If you know the specific arguments a function should take, define them explicitly for better type hinting and clarity.*args
and **kwargs
.
Interview Tip
Be prepared to explain the difference between *args
and **kwargs
, how they work, and when to use them. A good answer should demonstrate your understanding of packing and unpacking arguments, and provide examples of real-world applications.
When to use them
Use *args
when you need a function to accept an arbitrary number of positional arguments and the order matters. Use **kwargs
when you need a function to accept an arbitrary number of keyword arguments, where the order doesn't matter but the names (keys) are important.
Memory footprint
Using *args
and **kwargs
doesn't inherently create a significant memory overhead. However, be mindful of the number of arguments passed to the function. Passing extremely large lists or dictionaries can impact memory usage. The memory footprint increases linearly with the number and size of the arguments stored within the args
tuple or kwargs
dictionary.
Alternatives
If you know the specific arguments a function will receive, defining them explicitly is generally better than using *args
and **kwargs
. Python's type hinting also becomes easier and more effective. If the set of possible parameters is known and limited, consider using a dictionary with default values instead of **kwargs
.
Pros
Cons
FAQ
-
What happens if I pass a keyword argument to a function that only uses *args?
You will get aTypeError
. Python will try to interpret the keyword argument as a positional argument, but since the function is only expecting positional arguments defined with*args
, it will fail. -
Can I have regular positional arguments before *args?
Yes, you can. For example:def my_function(a, b, *args, **kwargs):
. In this case, the first two arguments must be passed positionally, and then any remaining positional arguments will be collected into theargs
tuple. -
What is the order of arguments when using both *args and **kwargs?
The order must be: regular positional arguments,*args
(positional arguments), and then**kwargs
(keyword arguments).