This content originally appeared on DEV Community and was authored by Rahul Gupta
Welcome to Day 14 of the 100 Days of Python series!
Today we’re going to unlock the magic behind flexible function arguments — *args
and `kwargs`. These let your functions accept **any number of arguments, making your code more dynamic, reusable, and powerful.
What You’ll Learn
- What
*args
and**kwargs
are - When and how to use them
- How to combine them with regular arguments
- Real-world examples
1. What Are *args
?
*args
lets your function accept any number of positional arguments as a tuple.
Example:
def add_numbers(*args):
total = sum(args)
print("Sum:", total)
add_numbers(1, 2)
add_numbers(10, 20, 30)
Output:
Sum: 3
Sum: 60
You can loop through args
like a list:
def show_args(*args):
for arg in args:
print(arg)
2. What Are **kwargs
?
**kwargs
lets your function accept any number of keyword arguments (named arguments) as a dictionary.
Example:
def print_info(**kwargs):
for key, value in kwargs.items():
print(f"{key}: {value}")
print_info(name="Alice", age=30, city="New York")
Output:
name: Alice
age: 30
city: New York
3. Using Both Together
You can use *args
and **kwargs
in the same function:
def demo_function(*args, **kwargs):
print("Positional arguments:", args)
print("Keyword arguments:", kwargs)
demo_function(1, 2, 3, name="Alice", job="Engineer")
Output:
Positional arguments: (1, 2, 3)
Keyword arguments: {'name': 'Alice', 'job': 'Engineer'}
Always put
*args
before**kwargs
in the function definition.
4. Default + Flexible Parameters
You can mix regular, *args
, and **kwargs
:
def send_email(to, subject, *attachments, **headers):
print("To:", to)
print("Subject:", subject)
print("Attachments:", attachments)
print("Headers:", headers)
send_email(
"user@example.com",
"Meeting Notes",
"file1.pdf", "file2.png",
priority="high", read_receipt=True
)
5. Unpacking with *
and **
You can pass a list or dictionary into a function using *
and **
:
def greet(name, age):
print(f"Hello {name}, you're {age} years old.")
info = {"name": "Bob", "age": 25}
greet(**info) # Unpacks dictionary as keyword arguments
nums = [5, 10]
def multiply(x, y):
print(x * y)
multiply(*nums) # Unpacks list as positional arguments
Real-World Example: Logging
def log_event(event_type, *args, **kwargs):
print(f"[{event_type.upper()}]")
for arg in args:
print(f"- Detail: {arg}")
for key, val in kwargs.items():
print(f"- {key}: {val}")
log_event(
"error",
"File not found", "User logged out",
filename="report.pdf", user="admin"
)
Best Practices
Use
*args
when you’re not sure how many positional arguments will be passed.Use
**kwargs
to accept any number of named arguments.Use descriptive names instead of just
args
andkwargs
for clarity (e.g.,*numbers
,**options
).Don’t overuse them where explicit parameters make more sense.
Recap
Today you learned:
- How
*args
collects extra positional arguments - How
**kwargs
collects extra keyword arguments - How to combine them with regular parameters
- How to unpack values using
*
and**
- Real-world examples like logging and flexible APIs
This content originally appeared on DEV Community and was authored by Rahul Gupta