*args and **kwargs let you define functions that accept a variable number of arguments. *args collects extra positional arguments into a tuple; **kwargs collects extra keyword arguments into a dictionary. The names args and kwargs are conventions—you can use other names, but the single * and double ** are required. This article shows how they work and when they are useful.
What they do
Inside the function, args is a tuple of all extra positional arguments, and kwargs is a dict of all extra keyword arguments. They do not include any arguments that were matched by earlier parameters. See Functions basics and Default arguments for normal parameters.
*args — multiple positional arguments
Use *args when the number of positional arguments is unknown or variable:
def sum_numbers(*args):
total = 0
for num in args:
total += num
return total
print(sum_numbers(1, 2, 3)) # 6
print(sum_numbers(1, 2, 3, 4, 5)) # 15
You can mix normal parameters with *args. The normal ones get the first arguments; the rest go into args:
def greet(greeting, *names):
for name in names:
print(f"{greeting}, {name}!")
greet("Hello", "Alice", "Bob") # Hello, Alice! / Hello, Bob!
**kwargs — multiple keyword arguments
**kwargs collects any keyword arguments that were not matched by earlier parameters into a dictionary:
def print_info(**kwargs):
for key, value in kwargs.items():
print(f"{key}: {value}")
print_info(name="Alice", age=30, city="NYC")
# name: Alice
# age: 30
# city: NYC
Order of parameters
When you use both, *args must come before **kwargs. The usual order is: normal args, then *args, then keyword-only args (if any), then **kwargs:
def example(a, b, *args, **kwargs):
print("a:", a, "b:", b)
print("args:", args)
print("kwargs:", kwargs)
example(1, 2, 3, 4, x=5, y=6)
# a: 1 b: 2
# args: (3, 4)
# kwargs: {'x': 5, 'y': 6}
Using both: pass-through (e.g. decorators)
Wrappers and decorators often accept *args, **kwargs and pass them to the wrapped function:
def example(*args, **kwargs):
print("Positional:", args)
print("Keyword:", kwargs)
def wrapper(func):
def inner(*args, **kwargs):
print("Calling", func.__name__)
return func(*args, **kwargs)
return inner
When to use them
*args: Variable number of positional arguments (e.g. sum, min, or “all remaining”).**kwargs: Flexible options or config (e.g. optional settings, or passing through to another API).- Both: Wrappers, decorators, or any function that must forward unknown arguments.
Next steps: Core Concepts · Decorators · Default arguments · Functions