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 theargstuple. -
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).