What are *args and **kwargs in Python?
Learn what *args and **kwargs mean in Python, how they collect positional and keyword arguments, parameter ordering rules, and real code examples.
Expected Interview Answer
*args and **kwargs let a Python function accept a variable number of arguments: *args collects any extra positional arguments into a tuple, and **kwargs collects any extra keyword arguments into a dict, so the function does not need a fixed, pre-declared parameter list.
The names args and kwargs are just convention — the meaningful part is the * and ** unpacking operators, which can be used with any identifier. Inside the function, args is a regular tuple you can iterate or index, and kwargs is a regular dict you can access with .items() or by key. The same * and ** syntax also works in reverse at a call site to unpack an existing list/tuple into positional arguments or a dict into keyword arguments. Parameter ordering rules matter: standard positional parameters come first, then *args, then keyword-only parameters, then **kwargs. This pattern is heavily used for wrapper/decorator functions that need to forward arbitrary arguments to another function without knowing its exact signature.
- Lets a function accept a flexible, unknown number of arguments
- Enables generic wrappers/decorators that forward calls transparently
- Same * / ** syntax works for unpacking at the call site too
- Keeps function signatures simple for common cases, flexible for edge cases
- Standard, idiomatic pattern recognized by every Python developer
AI Mentor Explanation
*args is like a net bowler who can send down however many deliveries a batter asks for in a session — three, ten, or twenty, all bundled into one practice tuple of balls faced. **kwargs is like a scoring app where you tag each delivery with labeled extras (wide=1, noball=1) that get collected into one dictionary of named stats, however many labels you choose to attach.
Step-by-Step Explanation
Step 1
*args collects positional args
Extra positional arguments passed to the function are gathered into a tuple named args.
Step 2
**kwargs collects keyword args
Extra keyword arguments are gathered into a dict named kwargs, keyed by argument name.
Step 3
Names are convention
The actual behavior comes from * and **; you could name them *values, **options instead.
Step 4
Parameter order
Standard params, then *args, then keyword-only params, then **kwargs, is the required declaration order.
Step 5
Unpacking at call sites
The same * and ** operators unpack an existing list/dict into arguments when calling a function.
Step 6
Typical use case
Decorators and wrapper functions use *args, **kwargs to forward any call signature to the wrapped function.
What Interviewer Expects
- Explains *args as a tuple and **kwargs as a dict of extra arguments
- Knows the names are convention; the * and ** are what matter
- Can state the correct parameter ordering rule
- Gives a real use case like decorators/wrappers
- Knows the same syntax also unpacks arguments at a call site
Common Mistakes
- Thinking 'args' and 'kwargs' are reserved keywords rather than conventional names
- Putting **kwargs before *args in a function signature
- Forgetting that *args is a tuple, not a list, so it can't be appended to
- Not knowing * and ** can also unpack at the call site, e.g. func(*my_list)
Best Answer (HR Friendly)
“*args and **kwargs let a function accept any number of extra inputs without the developer having to list them all in advance. *args handles extra unnamed values, and **kwargs handles extra named values, which makes functions flexible enough to wrap or forward calls to other functions.”
Code Example
def describe(*args, **kwargs):
print("positional:", args)
print("keyword:", kwargs)
describe(1, 2, 3, name="Ada", role="engineer")
# positional: (1, 2, 3)
# keyword: {'name': 'Ada', 'role': 'engineer'}
def wrapper(*args, **kwargs):
print("calling with", args, kwargs)
return describe(*args, **kwargs) # forward everything
wrapper(9, label="test")
# calling with (9,) {'label': 'test'}
# positional: (9,)
# keyword: {'label': 'test'}Follow-up Questions
- What is the required order of *args and **kwargs relative to normal parameters?
- How do you unpack a list into positional arguments at a call site?
- Why are *args and **kwargs commonly used in decorators?
- Can you have keyword-only arguments after *args?
- What data types are args and kwargs inside the function body?
MCQ Practice
1. Inside a function, what data type is args from *args?
*args collects extra positional arguments into a tuple, an immutable ordered sequence.
2. Inside a function, what data type is kwargs from **kwargs?
**kwargs collects extra keyword arguments into a dict, mapping argument names to values.
3. Which parameter ordering is valid in a function definition?
Standard positional parameters must come first, followed by *args, then **kwargs; kwargs must always be last.
Flash Cards
What does *args collect into? — A tuple of extra positional arguments.
What does **kwargs collect into? — A dict of extra keyword arguments.
Are 'args' and 'kwargs' reserved keywords? — No — they're just convention; the * and ** operators are what matter.
Where must **kwargs appear in a function signature? — Last, after any *args and keyword-only parameters.