*args & **kwargs
Overview
Sometimes you design a function without knowing exactly how many arguments it will receive. Python solves this with *args (arguments) and **kwargs (keyword arguments). *args captures all extra positional arguments into a Tuple. **kwargs captures all extra keyword arguments into a Dictionary. These tools are the backbone of writing flexible wrappers, decorators, and generic API handlers.
Syntax
# Accepts any number of positional arguments
def sum_all(*args):
print("Args type:", type(args)) # <class 'tuple'>
return sum(args)
print(sum_all(1, 2, 3, 4, 5)) # 15
# Accepts any number of keyword arguments
def print_user_profile(**kwargs):
print("Kwargs type:", type(kwargs)) # <class 'dict'>
for key, value in kwargs.items():
print(f"{key}: {value}")
print_user_profile(name="Alice", age=28, role="Admin")Common Pitfalls
- Order enforcement. You MUST order parameters correctly: standard arguments first, then
*args, then**kwargs. Writingdef func(**kwargs, *args):is an immediate SyntaxError. - Believing
argsandkwargsare reserved keywords. The magic is in the asterisks (*and**). You could legally name them*dataand**options, but deviating from standard naming conventions will severely confuse other developers.
Interview Questions
By placing a solitary * in the parameter list. For example: def create_user(*, name, age):. Calling create_user('Alice', 25) will fail with a TypeError; you are strictly forced to call create_user(name='Alice', age=25).
Real-World Example
A wrapper function that transparently passes all unknown arguments down to another target function.
def execute_and_log(func, *args, **kwargs):
print(f"[LOG] Executing function: {func.__name__}")
# Passing the arguments forward requires the unpacking operators
result = func(*args, **kwargs)
print(f"[LOG] Result: {result}")
return resultCheck Your Knowledge
Test your understanding of *args & **kwargs with these quick questions.