Keyword Arguments (**kwargs)
Learn to accept any number of keyword arguments with **kwargs.
**kwargs allows functions to accept any number of keyword arguments, providing ultimate flexibility for function calls with named parameters stored as a dictionary.
π Concepts & Theory
kwargs allows functions to accept any number of keyword (named) arguments. The double asterisk () unpacks keyword arguments into a dictionary.
Basic kwargs Syntax:
kwargs):def function_name(
# kwargs is a dictionary
for key, value in kwargs.items():
print(f"{key}: {value}")
Simple Example:
def print_info(kwargs):
for key, value in kwargs.items():
print(f"{key} = {value}")
print_info(name="Alice", age=30, city="NYC")
# name = Alice
# age = 30
# city = NYC
Building User Profiles:
details):def create_profile(
profile = {
"username": details.get("username", "anonymous"),
"email": details.get("email"),
"age": details.get("age"),
}
return profile
user = create_profile(username="alice", email="[email protected]", age=25)
Accessing kwargs:
def process(kwargs):
# Get with default
name = kwargs.get("name", "Unknown")
# Check if key exists
if "age" in kwargs:
print(f"Age: {kwargs['age']}")
# Iterate all
for key, value in kwargs.items():
print(f"{key}: {value}")
Mixing Parameters with kwargs:
def greet(greeting, kwargs):
name = kwargs.get("name", "there")
age = kwargs.get("age")
msg = f"{greeting}, {name}!"
if age:
msg += f" You are {age} years old."
return msg
greet("Hello", name="Alice", age=30)
Complete Parameter Order:**
def full_function(required, *args, keyword_only, **kwargs):
pass
# Call examples:
full_function(
1, # required
2, 3, # *args
keyword_only=4, # keyword_only
extra1=5, # kwargs
extra2=6 # kwargs
)
Common Use Cases:
1. Configuration Functions:
def configure_server(config):
host = config.get("host", "localhost")
port = config.get("port", 8080)
debug = config.get("debug", False)
return f"Server: {host}:{port} (debug={debug})"
configure_server(host="0.0.0.0", port=5000, debug=True)
2. Building Dictionaries:
data):def build_user(
return {
"id": data.get("id"),
"name": data.get("name", "Anonymous"),
"created": datetime.now(),
data # Include all other kwargs
}
3. Flexible Object Creation:
specs):def create_car(
car = {
"brand": specs.get("brand", "Unknown"),
"model": specs.get("model", "Unknown"),
"year": specs.get("year", 2024)
}
car.update(specs) # Add any additional specs
return car
Unpacking Dictionaries:
def greet(name, age):
return f"{name} is {age}"
user_data = {"name": "Alice", "age": 30}
result = greet(user_data) # Unpacks dict into kwargs
# Same as: greet(name="Alice", age=30)
Combining *args and kwargs:
def super_flexible(*args, kwargs):
print("Positional:", args)
print("Keyword:", kwargs)
super_flexible(1, 2, 3, name="Alice", age=30)
# Positional: (1, 2, 3)
# Keyword: {'name': 'Alice', 'age': 30}
Forwarding Arguments:
kwargs):def wrapper(
# Pass all kwargs to another function
return actual_function(kwargs)
Type Hints (Python 3.8+):
from typing import Any
def process(kwargs: Any) -> dict:
return kwargs
Best Practices:
- Use descriptive parameter name:
options,settings,**metadata - Document expected keywords
- Provide sensible defaults with .get()
- Validate required keywords
- Consider if explicit parameters would be clearer
π― Your Challenge
Create a function build_user(**user_data) that creates and returns a dictionary with all provided keyword arguments.
π Starter Code
def build_user(**user_data):
pass
- Use **user_data to accept any keyword arguments
- **kwargs automatically creates a dictionary
- Simply return the user_data dictionary
- No need for loops or processing in this simple case
- The function should accept and return all provided keyword arguments
Solution
def build_user(**user_data):
return user_data
Explanation
This function demonstrates **kwargs at its simplest. The ** before user_data tells Python to collect all keyword arguments into a dictionary. When you call build_user(name="Alice", age=30, email="[email protected]"), Python creates user_data = {"name": "Alice", "age": 30, "email": "[email protected]"}. Since we want to return exactly that dictionary, we simply return user_data. The function is flexibleβit accepts any keyword arguments without defining them explicitly. You could call it with any combination of keys: build_user(username="bob") or build_user(first="John", last="Doe", city="NYC") all work.
β οΈ Common Mistakes to Avoid
- Forgetting the ** in the parameter definition
- Trying to access kwargs with dot notation (it's a dict, not object)
- Not using .get() for optional keys (causes KeyError)
- Expecting kwargs to be ordered in old Python versions
- Modifying the original kwargs dict and causing side effects