Mastering how to use *args and kwargs in Python 3 is one of the most powerful and frequently used advanced techniques at Progressive Robot — these special syntaxes allow functions to accept a variable number of positional (*args) and keyword (**kwargs) arguments, making your code more flexible, reusable, generic, and future-proof for everything from utility functions, decorators, API wrappers, logging, data processors, CLI tools, to framework-level code.
In this comprehensive 2025–2026 Progressive Robot guide, you’ll learn exactly **how to use *args and kwargs in Python 3: basic usage, combining with normal parameters, argument ordering rules, unpacking in function calls, real-world patterns, best practices, common mistakes, and modern tips. All examples are tested on Python 3.10–3.13.
Key Takeaways – args and kwargs in Python 3
- args and kwargs in Python 3 let functions accept arbitrary numbers of arguments without fixed signatures.
- *args → collects positional arguments into a tuple.
- **kwargs → collects keyword arguments into a dictionary.
- Argument order rule (must follow this): normal params → *args → keyword-only params → **kwargs.
- Use *args for flexible positional inputs (e.g., sum of any numbers).
- Use **kwargs for flexible named options (e.g., config, logging levels).
- Unpack with * and ** when calling functions.
- Very common in decorators, logging, data pipelines, APIs, and third-party library code.
- Always prefer explicit parameters when number and meaning are known — use *args/**kwargs for extensibility.
Prerequisites
- Python 3.8+ installed (Progressive Robot recommends 3.12+)
- Basic Python knowledge (functions, parameters, return)
- Interactive shell (python3) or script file
1. Basic Usage – How to Use *args in Python 3
def add_numbers(*args):
"""Sum any number of positional arguments."""
total = 0
for num in args:
total += num
return total
print(add_numbers(5, 10)) # 15
print(add_numbers(1, 2, 3, 4, 5)) # 15
print(add_numbers()) # 0 (empty args → 0)
2. How to Use **kwargs in Python 3
def print_profile(**kwargs):
"""Print user profile from keyword arguments."""
for key, value in kwargs.items():
print(f"{key.capitalize()}: {value}")
print_profile(name="Zain", age=30, city="Karachi", role="Developer")
# Name: Zain
# Age: 30
# City: Karachi
# Role: Developer
3. Combining Normal Parameters, *args & **kwargs
Correct order (must follow this rule):
def complex_func(a, b, *args, x="default", y="value", **kwargs):
print(f"Fixed: a={a}, b={b}")
print(f"Args: {args}")
print(f"Keyword-only: x={x}, y={y}")
print(f"Kwargs: {kwargs}")
complex_func(10, 20, 30, 40, x="custom", color="blue", debug=True)
Output:
Fixed: a=10, b=20
Args: (30, 40)
Keyword-only: x=custom, y=value
Kwargs: {'color': 'blue', 'debug': True}
4. Unpacking *args and **kwargs When Calling Functions
def multiply(x, y, z):
return x * y * z
# Unpack tuple/list with *
numbers = (2, 3, 4)
print(multiply(*numbers)) # 24
# Unpack dict with **
options = {"x": 5, "y": 6, "z": 7}
print(multiply(**options)) # 210
5. Real-World Progressive Robot Examples
Flexible Logger
def log(level: str, message: str, *args, **kwargs):
"""Progressive Robot standard logger."""
print(f"[{level.upper()}] {message}", *args)
if kwargs:
print("Extra info:", kwargs)
log("INFO", "User logged in", user_id=123, ip="192.168.1.1")
# [INFO] User logged in user_id=123 ip=192.168.1.1
# Extra info: {'user_id': 123, 'ip': '192.168.1.1'}
Generic Data Processor
def process_data(data_type: str, *records, **options):
"""Process any number of records with options."""
print(f"Processing {data_type} records...")
for rec in records:
print(rec)
print("Options:", options)
process_data("users", {"id": 1, "name": "Zain"}, {"id": 2, "name": "Alice"},
format="json", dry_run=True)
6. Best Practices & Modern Tips (2025–2026 – Progressive Robot Style)
- Use *args and **kwargs only when number of args is truly variable.
- Prefer explicit parameters when args have fixed meaning.
- Always follow argument order: positional → *args → keyword-only → **kwargs.
- Add type hints: def func(*args: int, **kwargs: str) -> None:
- Use descriptive names: *messages, **config instead of just *args/**kwargs.
- Document *args/**kwargs clearly in docstrings.
- Avoid deep *args/**kwargs nesting — refactor into classes or dataclasses.
How to Use *args and **kwargs in Python 3 – FAQ (2025–2026)
- **How do I use *args and kwargs in Python 3?
*args collects positional args into tuple; **kwargs collects keyword args into dict — core way to use args and kwargs in Python 3. - **What is the correct order of arguments with *args and kwargs?
normal → *args → keyword-only → **kwargs — mandatory rule. - **How do I unpack *args and kwargs when calling functions in Python 3?
Use *tuple for positional, **dict for keyword — very powerful. - **When should I use *args and kwargs in Python 3?
When number of arguments is unknown or should stay flexible (logging, decorators, wrappers). - **What’s the difference between *args and kwargs in Python 3?*
args → positional (tuple); **kwargs → keyword/named (dict).
Summary
You now know exactly **how to use *args and kwargs in Python 3: collecting variable arguments, combining with fixed params, correct ordering, unpacking, real-world logging & processing examples, and Progressive Robot best practices.
Mastering args and kwargs in Python 3 gives your functions extreme flexibility — essential for building generic utilities, decorators, logging systems, CLI tools, API clients, and extensible code at Progressive Robot.
Recommended Next Tutorials
- Python Decorators – Advanced Function Wrapping
- Python Type Hints & Annotations (2025–2026)
- Python Function Scope & Closures
- Build a Flexible Logger / CLI Tool with *args & **kwargs
- Python Functions & Arguments Cheat Sheet