What do *args and **kwargs mean in a function definition? What do * and ** do in a function call? What is a keyword-only parameter?
Show the explanation
In a definition, they collect extra arguments
def log(level, *args, sep=" ", **kwargs):
# args -> a tuple of the extra positional arguments
# kwargs -> a dict of the extra keyword arguments
print(level, sep.join(map(str, args)), kwargs)
log("INFO", "user", 42, sep="|", ip="10.0.0.1")
# INFO user|42 {'ip': '10.0.0.1'}The names args and kwargs are only a convention. The * and ** do the work.
In a call, they unpack
point = (3, 4); opts = {"sep": "-"}
log("DEBUG", *point, **opts) # same as log("DEBUG", 3, 4, sep="-")Keyword-only parameters come after *args or a bare *, and callers must pass them by name:
def connect(host, port, *, timeout=5, retries=3): ...
connect("db", 5432, timeout=10) # OK
connect("db", 5432, 10) # TypeErrorThis stops mistakes such as passing arguments in the wrong order, and makes call sites easier to read.
Positional-only parameters (Python 3.8+) come before a /: def f(a, b, /, c). Callers cannot pass a and b by name, which lets you rename them later without breaking anyone.
The full order is def f(pos_only, /, normal, *args, kw_only, **kwargs).
Typical uses: wrapper functions and decorators that forward everything (return func(*args, **kwargs)), and functions such as print or max that take any number of arguments.
Original UniCircle question. Last reviewed 22 Oct 2026.
