Topic 58 of 64
**kwargs
Overview
**kwargs captures any number of keyword arguments into a dictionary. Combined with *args, it enables fully flexible function signatures — the foundation of Python's decorator pattern, ORM APIs, and framework configuration.
Syntax
python
def print_config(**kwargs):
for key, value in kwargs.items():
print(f" {key} = {value}")
print_config(host="localhost", port=5432, debug=True)
# **kwargs is a dict inside the function
def create(**kwargs: str) -> dict:
return kwargs
result = create(name="Alice", role="admin")
# {'name': 'Alice', 'role': 'admin'}
# Spread a dict with **
config = {"host": "localhost", "port": 5432}
print_config(**config) # same as print_config(host="localhost", port=5432)Common Pitfalls
- **kwargs must be the last parameter in a function signature.
- Keys in **kwargs must be valid Python identifiers — you can't pass 'my-key'='value' directly (use **{'my-key': 'value'}).
- Interview tip: The full flexible signature order is: def func(pos, /, std, *args, kw_only, **kwargs). Knowing this is an advanced interview signal.
Real-World Example
A flexible model constructor using **kwargs
example
python
class User:
ALLOWED = {"name", "email", "age", "role"}
def __init__(self, **kwargs):
unknown = set(kwargs) - self.ALLOWED
if unknown:
raise ValueError(f"Unknown fields: {unknown}")
for key, value in kwargs.items():
setattr(self, key, value)
def __repr__(self):
attrs = {k: getattr(self, k) for k in self.ALLOWED if hasattr(self, k)}
return f"User({attrs})"
u = User(name="Alice", email="alice@x.com", role="admin")
print(u)