Python
Programming
Coding Concepts
Function Arguments
Advanced Python Syntax

Use of *args and **kwargs

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

*args and **kwargs let a Python function accept a flexible number of arguments. They are useful when you are writing wrappers, forwarding calls, or designing APIs that need optional extra input without exploding the function signature.

What *args Actually Captures

*args collects extra positional arguments into a tuple.

python
1def add_all(*args):
2    return sum(args)
3
4
5print(add_all(1, 2, 3))
6print(add_all(10, 20, 30, 40))

Output:

text
6
100

The name args is conventional, but not magical. This works too:

python
def add_all(*numbers):
    return sum(numbers)

What matters is the leading *, not the variable name.

What **kwargs Captures

**kwargs collects extra keyword arguments into a dictionary.

python
1def build_profile(name, **kwargs):
2    profile = {"name": name}
3    profile.update(kwargs)
4    return profile
5
6
7print(build_profile("Ada", role="Engineer", language="Python"))

Output:

text
{'name': 'Ada', 'role': 'Engineer', 'language': 'Python'}

Again, the name kwargs is a convention. The ** is what tells Python to pack remaining named arguments into a mapping.

Inside a function definition, *args and **kwargs pack values together. At a call site, * and ** can unpack values back out.

python
1def greet(first_name, last_name, punctuation="!"):
2    return f"Hello, {first_name} {last_name}{punctuation}"
3
4
5parts = ("Grace", "Hopper")
6options = {"punctuation": "."}
7
8print(greet(*parts, **options))

Output:

text
Hello, Grace Hopper.

This symmetry is why *args and **kwargs are so common in wrapper functions. You can accept flexible input and forward it with very little boilerplate.

A Useful Wrapper Example

Here is a simple timing decorator that forwards any positional and keyword arguments to the wrapped function:

python
1import time
2
3
4def timed(func):
5    def wrapper(*args, **kwargs):
6        start = time.perf_counter()
7        try:
8            return func(*args, **kwargs)
9        finally:
10            elapsed = time.perf_counter() - start
11            print(f"{func.__name__} took {elapsed:.6f}s")
12
13    return wrapper
14
15
16@timed
17def multiply(a, b, scale=1):
18    return a * b * scale
19
20
21print(multiply(3, 4, scale=2))

Without *args and **kwargs, writing reusable wrappers like this would be much more awkward.

Parameter Order Still Matters

Python still enforces parameter ordering rules. A common pattern is:

python
1def example(required, *args, debug=False, **kwargs):
2    print(required)
3    print(args)
4    print(debug)
5    print(kwargs)
6
7
8example("run", 1, 2, 3, debug=True, mode="fast")

Here:

  • 'required is a normal positional-or-keyword parameter'
  • '*args collects extra positional values'
  • 'debug becomes keyword-only because it appears after *args'
  • '**kwargs collects any remaining named values'

Understanding that order makes function signatures much easier to read.

When They Are Helpful

Good uses include:

  • decorators and wrappers
  • pass-through helper functions
  • plugin hooks that may accept optional metadata
  • APIs that intentionally allow extra named options

Not every function needs them. If a function always expects exactly three clear parameters, explicit names are usually better than flexible catch-all parameters.

Common Pitfalls

The biggest mistake is using *args or **kwargs when the function really has a fixed, known contract. That makes code harder to read and hides what callers are supposed to provide.

Another common issue is forgetting that args is a tuple and kwargs is a dictionary. They are collected containers, not magic argument streams.

Developers also sometimes mix up packing and unpacking. def f(*args) packs extra positional values in a definition, while f(*values) unpacks an iterable at a call site.

Finally, forwarding **kwargs blindly can hide misspelled option names. If the receiving function does not expect a key, the error may show up far away from where the bad value entered the system.

Summary

  • '*args collects extra positional arguments into a tuple.'
  • '**kwargs collects extra keyword arguments into a dictionary.'
  • The same * and ** syntax can unpack values at call sites.
  • They are especially useful in wrappers, decorators, and pass-through helpers.
  • Use them for flexibility, but prefer explicit parameters when the contract is fixed and known.

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.