Python *args and **kwargs Explained (Beginner-Friendly Guide)

If you’re learning Python, you’ve probably seen functions with *args and **kwargs. At first, they look strange — but actually, they’re just tools to make your functions more flexible and powerful.

In this post, we’ll break them down in plain English, with examples and real-world use cases.


🔹 What is *args?

*args allows a function to accept any number of positional arguments (without needing to define them one by one).
Inside the function, they are collected into a tuple.

👉 Example:

def add_numbers(*args):
    return sum(args)

print(add_numbers(1, 2, 3))       # 6
print(add_numbers(10, 20, 30, 40)) # 100

Here:

  • args = (1, 2, 3)
  • args = (10, 20, 30, 40)

When to use?

  • When you don’t know how many inputs your function will get.
  • Example: calculators, math operations, loggers.

🔹 What is **kwargs?

**kwargs allows a function to accept any number of keyword arguments (name=value).
Inside the function, they are collected into a dictionary.

👉 Example:

def show_profile(**kwargs):
    for key, value in kwargs.items():
        print(f"{key}: {value}")

show_profile(name="Alice", age=25, country="Indonesia")

Output:

name: Alice
age: 25
country: Indonesia

Here:

  • kwargs = {"name": "Alice", "age": 25, "country": "Indonesia"}

When to use?

  • When you want flexible options or settings.
  • Example: user profiles, API parameters, configuration.

🔹 Real-World Use Cases

1. Logging System with *args

A logger function where you don’t know how many messages you’ll receive.

def log_message(*args):
    print("LOG:", " ".join(map(str, args)))

log_message("Error:", 404, "Not Found")
log_message("User", "Alice", "logged in")

Output:

LOG: Error: 404 Not Found
LOG: User Alice logged in

2. Database Connection with **kwargs

Easily handle default settings + overrides.

def connect_db(**kwargs):
    defaults = {"host": "localhost", "port": 5432}
    defaults.update(kwargs)
    print("Connecting with:", defaults)

connect_db(user="admin", password="123")
connect_db(host="db.server.com", user="root")

Output:

Connecting with: {'host': 'localhost', 'port': 5432, 'user': 'admin', 'password': '123'}
Connecting with: {'host': 'db.server.com', 'port': 5432, 'user': 'root'}

3. API Request with Both

Combine them when you need both positional and keyword arguments.

def api_request(*args, **kwargs):
    print("Method & URL:", args)
    print("Options:", kwargs)

api_request("GET", "/users", auth="token123", timeout=5)

Output:

Method & URL: ('GET', '/users')
Options: {'auth': 'token123', 'timeout': 5}

🔹 Easy Analogy

  • *args → “Bring me items in a bag 📦 (order matters).”
  • **kwargs → “Bring me items with labels 🏷️ (names matter).”

✅ Takeaway

  • Use *args when you need a function with flexible positional inputs.
  • Use **kwargs when you need flexible named options.
  • Together, they make your functions more reusable and adaptable.

🔥 Next time you see *args and **kwargs, remember:
They’re just Python’s way of saying —
“Don’t worry about the number of inputs, I can handle it.”

Related: Web Scraping with Beautiful Soup: A Beginner’s Guide.

Related: Building a PostgreSQL AI Agent in 200 Lines of Python.


Discover more from Susiloharjo

Subscribe to get the latest posts sent to your email.

Discover more from Susiloharjo

Subscribe now to keep reading and get access to the full archive.

Continue reading