Python DISCUSSION

What do *args and **kwargs mean in a Python function signature, and when should I use them?

Started by prabhakaran args and kwargsargument unpackingkeyword-only argumentspositional-only parametersfunction signatures
4 replies 248 views 5 participants
Latest activity · 30 Sep 2026

What do *args and **kwargs mean in a Python function signature, and when should I use them?

prabhakaran Python Forum
#1

Library code I am reading is full of signatures like def send(self, *args, **kwargs): and calls like plot(*points, **style). I also found def move(x, y, *, speed=100): with a lone star, and a function with a / in its parameter list.

I understand positional and keyword arguments in simple cases. What do the single and double star do in a definition compared with a call, what are the bare * and / for, and is it good practice to accept *args, **kwargs in my own functions?

Community replies 4

Re: What do *args and **kwargs mean in a Python function signature, and when should I use them?

#2

In a definition the stars collect. *args gathers any extra positional arguments into a tuple and **kwargs gathers any extra keyword arguments into a dict. With def f(a, *args, **kwargs), the call f(1, 2, 3, mode="fast", retries=2) gives a = 1, args = (2, 3) and kwargs = {"mode": "fast", "retries": 2}. The names are only a convention; the stars do the work.

In a call the stars do the opposite and unpack: f(*[1, 2, 3]) is f(1, 2, 3), and f(**{"a": 1, "mode": "x"}) is f(a=1, mode="x"). Any iterable works after *; ** needs a mapping with string keys.

Re: What do *args and **kwargs mean in a Python function signature, and when should I use them?

#3

The bare markers restrict how arguments may be passed. Parameters after a lone * are keyword-only: with def move(x, y, *, speed=100), the call move(1, 2, 50) raises TypeError and you must write move(1, 2, speed=50). That is good for options where a bare number or True at the call site would be unreadable.

Parameters before a / (Python 3.8 and later) are positional-only: def clamp(v, lo, hi, /) cannot be called with v=5, which lets the author rename parameters later without breaking callers. The full order is positional-only, /, ordinary, *args or a bare *, keyword-only, **kwargs.

Re: What do *args and **kwargs mean in a Python function signature, and when should I use them?

#4

The main legitimate use is forwarding. A wrapper or decorator that does not care about the arguments passes them straight through: def wrapper(*args, **kwargs): return fn(*args, **kwargs). Put @functools.wraps(fn) on the wrapper so that the wrapped function keeps its name and docstring.

Subclasses use the same idea: def __init__(self, port, *args, **kwargs): super().__init__(*args, **kwargs) takes what it needs and hands the rest to the parent class, so the subclass keeps working when the parent gains a new option.

Re: What do *args and **kwargs mean in a Python function signature, and when should I use them?

#5

For ordinary functions prefer explicit parameters. def configure(**kwargs) hides the accepted options from the reader, from editor completion and from type checkers, and a misspelt option such as baudrte=9600 is silently accepted and ignored unless you validate the dict yourself. With explicit keyword parameters the same typo is an immediate TypeError.

*args is reasonable for genuinely variadic functions such as def average(*values): return sum(values) / len(values). Small details: args is a tuple, so it cannot be appended to, and kwargs is a new dict on every call. The same stars work in assignments, where first, *rest = [1, 2, 3, 4] gives rest = [2, 3, 4], and in literals, where {**defaults, **overrides} merges two dicts with later keys winning.

TEP COMMUNITY