DEV Community

Cover image for Day 14/100: Understanding *args and **kwargs in Python Functions
 Rahul Gupta
Rahul Gupta

Posted on

Day 14/100: Understanding *args and **kwargs in Python Functions

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)
Enter fullscreen mode Exit fullscreen mode

Output:

Sum: 3
Sum: 60
Enter fullscreen mode Exit fullscreen mode

You can loop through args like a list:

def show_args(*args):
    for arg in args:
        print(arg)
Enter fullscreen mode Exit fullscreen mode

🧠 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")
Enter fullscreen mode Exit fullscreen mode

Output:

name: Alice
age: 30
city: New York
Enter fullscreen mode Exit fullscreen mode

🧪 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")
Enter fullscreen mode Exit fullscreen mode

Output:

Positional arguments: (1, 2, 3)
Keyword arguments: {'name': 'Alice', 'job': 'Engineer'}
Enter fullscreen mode Exit fullscreen mode

🔺 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
)
Enter fullscreen mode Exit fullscreen mode

🔄 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
Enter fullscreen mode Exit fullscreen mode
nums = [5, 10]
def multiply(x, y):
    print(x * y)

multiply(*nums)  # Unpacks list as positional arguments
Enter fullscreen mode Exit fullscreen mode

🎯 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"
)
Enter fullscreen mode Exit fullscreen mode

🧼 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 and kwargs 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

Top comments (0)