Understand *args and **kwargs in Python
Collect and unpack arguments, define keyword-only parameters, avoid duplicate values, and preserve object-sharing semantics when forwarding calls.
In a function definition, *args collects extra positional arguments into a tuple, while **kwargs collects extra keyword arguments into a dictionary. In a call, * expands an iterable into positional arguments and ** expands a mapping into keyword arguments.
Collect arguments
def demo(first, *args, **kwargs):
print(first)
print(args)
print(kwargs)
demo(1, 2, 3, keyword1=5, keyword2=6)
# 1
# (2, 3)
# {'keyword1': 5, 'keyword2': 6}
Explicitly declared parameters consume their matching arguments first. args and kwargs are naming conventions; *values and **options work the same way.
Unpack a call
def add(a, b):
return a + b
numbers = [1, 2]
options = {"b": 10}
print(add(*numbers)) # 3
print(add(5, **options)) # 15
The * operand can be an iterable, not just a list. The ** operand must be a mapping with string keys, and those keys still have to fit the function signature unless it accepts extra keywords. Supplying the same parameter twice raises TypeError, even when the duplicate values are equal.
Forward calls without exposing argument data
import logging
logger = logging.getLogger(__name__)
def logged_call(func, *args, **kwargs):
logger.info("Calling %s", getattr(func, "__name__", type(func).__name__))
return func(*args, **kwargs)
This passes the objects through without copying them. Avoid logging all raw arguments by default: passwords, tokens, or large objects may be present.
Define keyword-only and positional-only parameters
def configure(name, /, *values, timeout=10, **options):
return name, values, timeout, options
print(configure("worker", 1, 2, timeout=5, retries=3))
Parameters before / are positional-only. Parameters after *args are keyword-only. A bare * introduces keyword-only parameters without collecting extra positional arguments:
def connect(host, *, timeout):
return host, timeout
connect("example.com", timeout=5)
A general definition orders positional-only parameters, positional-or-keyword parameters, optional *args, keyword-only parameters, and optional **kwargs, following Python's default-value rules.
FAQ
Can unpacking forms be combined? Yes: func(*values, **options) is common. Python also permits multiple unpackings, but duplicate keyword names and conflicting positional bindings still fail.
Can I modify args? The tuple itself is immutable. Converting it to a list lets you change the local collection, but mutable objects inside remain shared with the caller. Mutating one of those objects can still affect the caller.
References
Contact us
Join the community
to join the community
Try Guance
Start online and pay only for what you use.
Get startedChoose a Guance plan