What are *args and **kwargs in Python, and when do you use them?
py-jun-003
Your answer
Answer as you would in a real interview — explain your thinking, not just the conclusion.
Model answer
*args collects extra positional arguments into a tuple; **kwargs collects extra keyword arguments into a dict. They let you write functions that accept a variable number of arguments without knowing in advance how many will be passed. Common use cases: wrapper functions that forward arguments to another function (decorators, adapters), utility functions like log() that accept any number of messages, and mixing required and optional parameters. The names args/kwargs are conventions — the * and ** operators are what matter. You can also use * and ** at call sites to unpack sequences or dicts into positional or keyword arguments.
Code example
# *args: variable positional arguments -> tuple
def total(*args: float) -> float:
return sum(args)
print(total(1, 2, 3)) # 6.0
print(total(10, 20)) # 30.0
# **kwargs: variable keyword arguments -> dict
def create_user(**kwargs: str) -> dict:
return {"name": kwargs.get("name", "Anonymous"), **kwargs}
print(create_user(name="Alice", role="admin"))
# {'name': 'Alice', 'role': 'admin'}
# Combining both — order matters: positional, *args, keyword-only, **kwargs
def log(level: str, *messages: str, timestamp: bool = False, **context) -> None:
prefix = "[with timestamp]" if timestamp else ""
for msg in messages:
print(f"{level} {prefix} {msg} {context}")
log("INFO", "started", "ready", timestamp=True, service="api")
# Unpacking at call site
args = (1, 2, 3)
kwargs = {"sep": "-"}
print(*args) # positional unpack
# print(**kwargs) — spreads into keyword args of print()
Follow-up
What is the difference between positional-only parameters (/) and keyword-only parameters (*) in Python 3.8+ function signatures?