Python
kwargs
programming
coding
Python functions

What is the purpose and use of kwargs?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

In Python, **kwargs lets a function accept an arbitrary set of named keyword arguments. It is useful when a function needs to be extensible, forward options to another function, or support wrappers and decorators without listing every possible keyword in advance.

What **kwargs Actually Does

Inside a function, **kwargs collects extra keyword arguments into a dictionary.

python
1def describe_user(**kwargs):
2    for key, value in kwargs.items():
3        print(f"{key} = {value}")
4
5
6describe_user(name="Ava", role="admin", active=True)

This is different from ordinary named parameters such as name or role, which must appear explicitly in the function signature. **kwargs is the catch-all for named options that were not matched by earlier parameters.

The name kwargs is only a convention. You could write **options, but **kwargs is the name most Python developers expect.

Combine Explicit Parameters with **kwargs

A common pattern is to keep important parameters explicit and use **kwargs only for optional extras.

python
1def create_user(username, email, **kwargs):
2    user = {
3        "username": username,
4        "email": email,
5    }
6    user.update(kwargs)
7    return user
8
9
10print(create_user("ava", "[email protected]", timezone="UTC", team="platform"))

This keeps the main contract clear while leaving room for extension. That balance is usually better than making everything optional and hiding the real interface behind a giant kwargs dictionary.

Forward Keyword Arguments to Another Function

One of the most useful applications is forwarding options through a wrapper or helper.

python
1def connect(host, timeout=5, retries=2):
2    return f"connect host={host} timeout={timeout} retries={retries}"
3
4
5def connect_with_logging(host, **kwargs):
6    print("Connecting with options", kwargs)
7    return connect(host, **kwargs)
8
9
10print(connect_with_logging("api.internal", timeout=10))

This avoids duplicating every supported keyword in intermediate wrapper layers. It is especially useful in library code, framework hooks, and adapter functions.

**kwargs Is Important in Decorators

Decorators often need to accept whatever arguments the wrapped function accepts. *args and **kwargs together make that possible.

python
1from functools import wraps
2
3
4def trace(fn):
5    @wraps(fn)
6    def wrapper(*args, **kwargs):
7        print(f"calling {fn.__name__} args={args} kwargs={kwargs}")
8        return fn(*args, **kwargs)
9    return wrapper
10
11
12@trace
13def add(x, y=0):
14    return x + y
15
16
17print(add(4, y=7))

Without **kwargs, many decorators would break when the caller used keyword-style arguments.

Validate Unknown Keys When It Matters

**kwargs gives flexibility, but too much flexibility can hide bugs. If the function only supports a known set of optional keys, validate them.

python
1def configure(**kwargs):
2    allowed = {"timeout", "retries", "verbose"}
3    unknown = set(kwargs) - allowed
4    if unknown:
5        raise ValueError(f"Unknown options: {sorted(unknown)}")
6    return kwargs
7
8
9print(configure(timeout=3, retries=1))

This catches typos such as timout=3 early instead of letting them silently do nothing.

*args and **kwargs Together

Python allows both variable positional arguments and variable keyword arguments in the same signature.

python
1def debug_call(*args, **kwargs):
2    print("args", args)
3    print("kwargs", kwargs)
4
5
6debug_call(1, 2, env="prod", dry_run=True)

This combination is useful for generic wrappers, but it also makes the public API less explicit, so it should be used with intent rather than as a default habit.

When **kwargs Helps and When It Hurts

**kwargs is helpful when:

  • the function is a wrapper or decorator
  • options may evolve over time
  • the function forwards arguments downstream

It hurts when:

  • the supported arguments are actually fixed and known
  • the public API becomes hard to discover
  • validation is skipped and typos become silent bugs

The best rule is to keep the stable core explicit and reserve **kwargs for genuine extension points.

Common Pitfalls

The biggest mistake is accepting arbitrary keyword arguments and never validating them. Another is using **kwargs as a shortcut to avoid thinking about API design, which makes call sites harder to understand and document. Developers also forward **kwargs into downstream functions without checking whether the option names really match, which can create confusing runtime failures.

Summary

  • '**kwargs collects extra named arguments into a dictionary.'
  • It is useful for extensible functions, wrappers, and decorators.
  • Keep important parameters explicit and use **kwargs for real extension points.
  • Validate supported keys when silent mistakes would be costly.
  • Use **kwargs to improve flexibility, not to hide an unclear API.

Course illustration
Course illustration

All Rights Reserved.