mailwal

Python From Scratch #36 - **kwargs in Python

Shefali Jangid

Python From Scratch #36 - **kwargs in Python

Learn how to use **kwargs to accept any number of keyword arguments in Python.

Hey 👋

Yesterday, we learned about *args, which lets a function accept any number of positional arguments.

Today, we’ll learn about **kwargs, which lets a function accept any number of keyword arguments.

If *args collects positional arguments, you can think of **kwargs as its keyword-argument counterpart.

Not sure what to learn next in web development?

ExpertEdge by Packt brings together 4,000+ books and courses with structured learning paths for roles like Full Stack Developer.

Explore resources on JavaScript, React, Node.js, TypeScript, and more.

Get a 7-day free trial and a flat 50% OFF the yearly plan with my code SHEFALI50.

Explore ExpertEdge →

What is **kwargs?

**kwargs allows a function to accept any number of keyword arguments.

For example:

def show_info(**kwargs):
    print(kwargs)

show_info(name="Shefali", age=27, city="Delhi")

# Output:

# {'name': 'Shefali', 'age': 27, 'city': 'Delhi'}

Python collects the keyword arguments into a dictionary.

We’ll learn more about dictionaries later. For now, remember: **kwargs collects multiple keyword arguments into one variable.

Why Do We Need **kwargs?

Normally, you define the parameters a function expects:

def introduce(name, age):
    print("Name:", name)
    print("Age:", age)

introduce(name="Shefali", age=27)

This works well when you know exactly which parameters you need.

But what if you want your function to accept additional named values?

That’s where **kwargs can help:

def introduce(**kwargs):
    print(kwargs)

introduce(name="Shefali", age=27, city="Delhi")

# Output:

# {'name': 'Shefali', 'age': 27, 'city': 'Delhi'}

The function can accept any number of keyword arguments.

kwargs Is Just a Name

Just like args, the name kwargs is not special.

The ** is what matters.

You could write:

def show_info(**details):
    print(details)

show_info(name="Shefali", age=27)

# Output:

# {'name': 'Shefali', 'age': 27}

But **kwargs is the common convention you’ll usually see in Python code.

*args vs **kwargs

This is the main difference:

          *args                                         **kwargs
  Accepts positional arguments                     Accepts keyword arguments
  Collected into a tuple                          Collected into a dictionary
          Uses one *                                     Uses two **

For example:

def show(*args, **kwargs):
    print(args)
    print(kwargs)

show(10, 20, name="Shefali", age=27)

# Output:

# (10, 20)
# {'name': 'Shefali', 'age': 27}

The positional arguments go into args.

The keyword arguments go into kwargs.

Looping Through **kwargs

Since kwargs is a dictionary, you can loop through it:

def show_info(**kwargs):
    for key, value in kwargs.items():
        print(key, ":", value)

show_info(name="Shefali", age=27, city="Delhi")

# Output:

# name : Shefali
# age : 27
# city : Delhi

Don’t worry too much about .items() yet. We’ll learn dictionaries properly later.

For now, the important idea is that kwargs contains named values.

Using **kwargs With Regular Parameters

You can also use regular parameters together with **kwargs.

For example:

def greet(name, **details):
    print("Hello", name)
    print(details)

greet("Shefali", age=27, city="Delhi")

# Output:

# Hello Shefali
# {'age': 27, 'city': 'Delhi'}

Here:

  • name receives "Shefali"

  • **details collects the remaining keyword arguments

*args and **kwargs Together

You can use both in the same function.

def show_info(*args, **kwargs):
    print("Positional:", args)
    print("Keyword:", kwargs)

show_info("Python", "JavaScript", name="Shefali", age=27)

# Output:

# Positional: ('Python', 'JavaScript')
# Keyword: {'name': 'Shefali', 'age': 27}

This gives the function a lot of flexibility.

You can pass:

  • any number of positional arguments

  • any number of keyword arguments

The Order Matters

When using regular parameters, *args, and **kwargs together, they follow a specific order.

For example:

def example(name, *args, **kwargs):
    print(name)
    print(args)
    print(kwargs)

example(
    "Shefali",
    "Python",
    "JavaScript",
    age=27,
    city="Delhi"
)

# Output:

# Shefali
# ('Python', 'JavaScript')
# {'age': 27, 'city': 'Delhi'}

The general order is:

regular parameters → *args → **kwargs

You don’t need to memorize every rule around function parameters yet. Just remember this order when you see them together.

Keyword Arguments Need Names

With **kwargs, you pass values using names:

show_info(name="Shefali", age=27)

This is different from *args:

show_info("Shefali", 27)

The first version uses keyword arguments.

The second version uses positional arguments.

That’s why Python can separate them when both *args and **kwargs are used.

A Practical Example

Imagine you’re creating a function to display information about a user.

You don’t know which pieces of information the caller wants to provide.

You could use:

def user_profile(**details):
    for key, value in details.items():
        print(key, ":", value)

user_profile(
    name="Shefali",
    age=27,
    city="Delhi"
)

# Output:

# name : Shefali
# age : 27
# city : Delhi

Another user could provide different information:

user_profile(
    name="John",
    country="India"
)

The same function can handle both.

That’s one reason **kwargs is useful.

A Common Mistake

Don’t confuse *args and **kwargs.

This:

def show(*args):
    print(args)

expects positional arguments: show(10, 20, 30)

While this:

def show(**kwargs):
    print(kwargs)

expects keyword arguments: show(name="Shefali", age=27)

The number of * characters matters.

  • *args → positional arguments

  • **kwargs → keyword arguments

What Happens If You Don’t Pass Anything?

Just like *args, you can call a **kwargs function without providing any arguments:

def show_info(**kwargs):
    print(kwargs)

show_info()

# Output:

# {}

You get an empty dictionary.

Try It Yourself

Now, a small exercise for you. Try these:

  • Create a function called count_details() that accepts any number of keyword arguments and prints how many were provided.

  • Create a function that accepts both *args and **kwargs and try printing the positional arguments and keyword arguments separately.

That’s all for today!

Tomorrow, we’ll learn about pass and recursion, including how a function can call itself.


If you enjoyed this newsletter, consider sharing it with another developer. And if you have any feedback, I’d love to hear it. It would genuinely mean a lot to me. ❤️


Want to sponsor my work? Let’s talk!

See you tomorrow ✨

- Shefali

If you enjoyed this edition of DevBits, you can support my work here ☕

Buy Me a Coffee

Your support helps me keep creating more developer tips, UI snippets, and helpful content for the community.

© 2026 Shefali Jangid
548 Market Street PMB 72296, San Francisco, CA 94104