In Python, functions can accept a variable number of arguments using two special syntaxes: *args and **kwargs. These allow you to write flexible functions that can handle different types of input.
Introduction to *args
The *args syntax allows a function to accept any number of positional arguments. The args name is not required, but it’s a common convention. When using *args, the function receives a tuple containing all the positional arguments passed to it.
Here’s an example:
def print_everything(*args):
for count, thing in enumerate(args):
print(f'{count}. {thing}')
print_everything('apple', 'banana', 'cabbage')
Output:
0. apple
1. banana
2. cabbage
Introduction to **kwargs
The **kwargs syntax allows a function to accept any number of keyword arguments. Like args, the kwargs name is not required, but it’s a common convention. When using **kwargs, the function receives a dictionary containing all the keyword arguments passed to it.
Here’s an example:
def table_things(**kwargs):
for name, value in kwargs.items():
print(f'{name} = {value}')
table_things(apple='fruit', cabbage='vegetable')
Output:
apple = fruit
cabbage = vegetable
Combining *args and **kwargs
You can use both *args and **kwargs in the same function definition. However, *args must come before **kwargs. This allows you to handle both positional and keyword arguments.
Here’s an example:
def func(required_arg, *args, **kwargs):
print(required_arg)
if args:
print(args)
if kwargs:
print(kwargs)
func("required argument", 1, 2, '3', keyword1=4, keyword2="foo")
Output:
required argument
(1, 2, '3')
{'keyword1': 4, 'keyword2': 'foo'}
Unpacking Arguments
You can also use the * and ** syntax when calling a function. This allows you to unpack lists or dictionaries into positional or keyword arguments.
Here’s an example:
def print_three_things(a, b, c):
print(f'a = {a}, b = {b}, c = {c}')
mylist = ['aardvark', 'baboon', 'cat']
print_three_things(*mylist)
Output:
a = aardvark, b = baboon, c = cat
Use Cases
*args and **kwargs are useful in various scenarios:
- Subclassing: When subclassing a class, you can use
*argsand**kwargsto pass arguments to the parent class’s constructor. - Wrapper functions: When writing wrapper functions or decorators, you can use
*argsand**kwargsto accept arbitrary arguments and pass them through to the wrapped function. - Dynamic argument handling: When working with dynamic data or APIs, you can use
*argsand**kwargsto handle variable numbers of arguments.
In summary, *args and **kwargs provide a flexible way to handle variable arguments in Python functions, making your code more adaptable and reusable.