*args and **kwargs
Accept an arbitrary number of positional or keyword arguments in a function definition.
def f(*args, **kwargs): ...
Purpose
A parameter prefixed with * collects any extra positional arguments into a tuple; one prefixed
with ** collects any extra keyword arguments into a dict. Together they let a function accept
a variable, unspecified-in-advance number of arguments.
Example
def total(*numbers: float) -> float:
return sum(numbers)
def describe(**details: str) -> str:
parts = [f"{key}={value}" for key, value in details.items()]
return ", ".join(parts)
total(1.5, 2.25, 3.0) # 6.75
describe(name="Ada", role="engineer") # "name=Ada, role=engineer"
Behavior notes
- The names
argsandkwargsare a strong convention, not a requirement β*itemsor**optionswork identically. What matters is the*/**prefix, not the name. *argscollects positional arguments beyond the ones already named;**kwargscollects keyword arguments that donβt match any named parameter. A function can have both, in that order, plus named parameters before them.- Since Python 3.7, a
dict(and so**kwargs) preserves insertion order β iterating overkwargs.items()visits entries in the order the caller passed them. - The reverse operation β spreading an existing sequence or mapping into a call β uses the same
*/**symbols at the call site:total(*[1.5, 2.25, 3.0])ordescribe(**{"name": "Ada"}). Same symbols, opposite direction: collecting when defining, spreading when calling.
Common mistakes
- Adding named parameters after
**kwargsin a definition β this isnβt allowed;**kwargs(like*args) has to be among the last parameters. - Reaching for
**kwargsfor a fixed, known set of options instead of naming them directly with defaults β named parameters are more discoverable and let type checkers and IDEs catch typos that**kwargswould silently swallow into the dict instead of flagging.
Implementation notes
Argument-collection semantics for *args/**kwargs are defined by the language grammar β
identical across conforming implementations.