Table of Contents

What Will You Learn
This tutorial explains how to use **kwargs in Python functions to accept any number of keyword arguments. You'll learn when and why to use them, how they interact with other parameters, and how to safely unpack and process them. These insights will help you write cleaner, more extensible, and dynamic functions for real-world applications.


As a beginner Python developer, learning how to use **kwargs is essential for writing flexible and scalable functions. This feature allows your code to handle any number of named arguments, making it highly adaptable for real-world scenarios such as APIs, configuration setups, or dynamic UI components. Instead of limiting yourself to fixed inputs, **kwargs lets your functions accept optional or unexpected keyword arguments without raising errors.

By mastering **kwargs, you gain full control over how your functions process named data. It also prepares you for reading and writing professional-level code, especially in frameworks and libraries where dynamic parameters are common. If you're building reusable components or want to extend existing functions without changing their core signature — this is a must-have skill.

What Is **kwargs in Python?

In Python, **kwargs stands for “keyword arguments” and is used to pass a variable number of named arguments into a function. These arguments are captured as a dictionary where the keys are argument names and the values are the passed data. The double asterisk ** tells Python to gather all keyword arguments that were not explicitly defined in the function signature.

**kwargs is useful when you don't know in advance which keyword arguments will be passed to your function, or when you're designing functions that should be easily extended in the future. It helps avoid errors from unexpected inputs and keeps the function flexible. Inside the function, you can loop through kwargs.items() to process each name-value pair. This is particularly useful in decorators, configuration functions, and when building wrappers or plugins. While *args collects unnamed positional arguments, **kwargs deals specifically with named ones. Together, they enable clean and reusable function definitions that can adapt to many use cases.

Here is a simple example demonstrating how to use **kwargs in a Python function:


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

    # Example usage
    print_details(name="John", age=25, city="New York")

In this example, the function print_details accepts any number of keyword arguments and prints them as key-value pairs.

How to Use **kwargs in Python

To use **kwargs in Python, include it in your function definition using a double asterisk followed by a parameter name, typically kwargs. This collects all keyword arguments not explicitly defined and stores them in a dictionary. You can access the values using standard dictionary methods such as .get() or iterate through the items. This is helpful when creating flexible and reusable functions. **kwargs must appear after all regular and *args parameters. It’s commonly used in APIs, decorators, and dynamic configuration functions.

Here is another example showing how to use **kwargs to create a flexible greeting function:


    def greet_user(greeting, **kwargs):
        user_info = ", ".join(f"{key}={value}" for key, value in kwargs.items())
        print(f"{greeting}! User details: {user_info}")

    # Example usage
    greet_user("Hello", name="Alice", age=30, location="Paris")
    greet_user("Welcome", username="JohnDoe", role="admin")

In this example, the function greet_user accepts a fixed greeting argument and any number of keyword arguments, which are formatted and displayed as user details.

How Does **kwargs Work in Python?

When a function uses **kwargs, Python collects all keyword arguments passed into the function and stores them as key-value pairs in a dictionary. This allows the function to accept any number of optional named arguments without breaking. Inside the function, you can inspect, use, or modify these values just like you would with a regular dictionary. This mechanism is extremely useful for dynamic behavior and customization.

  • Captures extra keyword arguments: Any argument in the form of key=value is collected.
  • Stores data in a dictionary: Access items using kwargs['key'] or kwargs.get('key').
  • Allows flexibility: You don’t need to predefine every possible parameter.
  • Supports optional config: You can pass custom settings to functions via **kwargs.
  • Used in decorators: Helps forward parameters from wrappers to wrapped functions.
  • Enhances reusability: One function can serve multiple purposes depending on input.
  • Combines with *args: Enables both positional and named argument collection.

How to Pass **kwargs in Python?

To pass **kwargs, use named arguments when calling a function. These are automatically collected into the kwargs dictionary if the function accepts **kwargs. If you already have a dictionary of key-value pairs, you can pass it using the double-asterisk syntax ** to unpack it. This approach is useful when forwarding arguments between functions or reading from a configuration object.


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

    describe_user(name="Alice", age=30, role="admin")

    # Using a dictionary
    user_data = {"name": "Bob", "age": 25}
    describe_user(**user_data)

How Does *args Differ from **kwargs in Python?

*args and **kwargs both allow functions to accept variable numbers of arguments, but they serve different purposes. *args is used to handle positional arguments and stores them in a tuple. In contrast, **kwargs handles keyword arguments and stores them in a dictionary. This means *args is for unnamed values, while **kwargs is for named values. You can use both in the same function, but their order matters: *args must come before **kwargs. Understanding the distinction helps you build flexible, professional-grade functions. Both are essential tools in any serious developer's toolbox.

Aspect *args **kwargs
Purpose Handles positional arguments Handles keyword arguments
Stored As Tuple Dictionary
Syntax *args **kwargs
Access By index By key
Used For Unknown number of values Unknown number of named options
Common Use Math functions, lists Settings, configuration
Definition Order Comes before **kwargs Must be last in parameter list

Common Beginner Mistakes

Using **kwargs Without Handling It

A common mistake is including **kwargs in a function definition and never using it. This confuses other developers and implies flexibility that doesn’t exist. If your function doesn’t need to process extra keyword arguments, you shouldn’t include **kwargs. Unused code adds noise and can cause misunderstandings about what the function accepts.


    # Incorrect
    def greet_user(name, **kwargs):
        print(f"Hello, {name}")  # kwargs ignored

    # Correct
    def greet_user(name):
        print(f"Hello, {name}")

Passing Positional Arguments to **kwargs

**kwargs only works with named arguments. Beginners often try to pass values without keys, expecting **kwargs to catch them. This leads to a TypeError. If you want to handle unnamed arguments, use *args instead. Always use key-value syntax when passing arguments intended for **kwargs.


    # Incorrect
    def show_data(**kwargs):
        print(kwargs)

    show_data("Alice", 30)  # TypeError

    # Correct
    show_data(name="Alice", age=30)

Incorrect Unpacking of Dictionary

When passing a dictionary to a function expecting **kwargs, forgetting to unpack it with ** causes it to be treated as a single argument. This often results in errors or unexpected behavior. Always use double asterisks when passing a dictionary as keyword arguments to a function that accepts **kwargs.


    # Incorrect
    def print_user(**kwargs):
        print(kwargs)

    data = {"name": "Bob", "role": "admin"}
    print_user(data)  # Incorrect

    # Correct
    print_user(**data)

Using Mutable Default Values Inside **kwargs

Some beginners try to assign default mutable values inside **kwargs like lists or dictionaries without checking if the key exists. This can lead to shared state bugs. Always check for key existence using .get() or conditional logic before using a mutable fallback.


    # Incorrect
    def config(**kwargs):
        settings = kwargs["options"]  # KeyError if missing

    # Correct
    def config(**kwargs):
        settings = kwargs.get("options", {})

Misordering Parameters

Another mistake is placing **kwargs before other parameters or *args. In Python, the correct order is: regular arguments → *args → default arguments → **kwargs. Failing to follow this order leads to syntax errors or unexpected behavior during function calls.


    # Incorrect
    def func(**kwargs, name):  # SyntaxError

    # Correct
    def func(name, **kwargs):
        print(name, kwargs)

Frequently Asked Questions about **kwargs Parameters

What does *args and **kwargs mean in Python?

In Python, *args and **kwargs are special parameters used to handle variable numbers of arguments in a function. *args collects extra positional arguments as a tuple, while **kwargs collects extra keyword arguments as a dictionary. This allows your function to remain flexible and reusable without knowing in advance how many inputs it will receive.

For example, *args is ideal for mathematical functions or lists of values, while **kwargs is perfect for configuration settings or named options. You can use both in the same function, and the standard order is: named parameters → *args → default values → **kwargs. Together, they make Python functions more powerful and adaptable.

How do I access values inside **kwargs?

Since **kwargs collects keyword arguments into a dictionary, you can access the values using standard dictionary methods. The most common approach is using kwargs.get("key") to retrieve a value safely, avoiding a KeyError if the key doesn’t exist. You can also iterate over kwargs.items() to loop through all key-value pairs inside the function.

Example:


      def user_info(**kwargs):
          name = kwargs.get("name", "Guest")
          for key, value in kwargs.items():
              print(f"{key}: {value}")

      user_info(name="Alice", role="admin")
Can I use both *args and **kwargs in the same function?

Yes, Python allows you to use both *args and **kwargs in a single function. This gives your function the flexibility to accept any combination of positional and keyword arguments. The rule is that *args must come before **kwargs in the function signature. This ordering ensures Python parses the arguments correctly during the function call.

Example:


      def mix_inputs(*args, **kwargs):
          print("Positional:", args)
          print("Named:", kwargs)

      mix_inputs(1, 2, name="Bob", active=True)
When should I use **kwargs instead of regular parameters?

Use **kwargs when your function needs to accept optional or unpredictable keyword arguments. This is common in APIs, GUI frameworks, and utility functions that require flexible configuration. If you expect a fixed set of inputs, use named parameters for clarity. But when inputs may vary based on context or user preference, **kwargs keeps your function adaptable and clean.

For example, instead of hardcoding style arguments in a UI component, you can allow users to pass their own keyword settings via **kwargs. This reduces code duplication and makes the function more scalable.

Can I pass a dictionary directly into a function that uses **kwargs?

Yes, you can pass a dictionary into a function that uses **kwargs, but you must unpack it using the double asterisk syntax: **dict. Without unpacking, the dictionary would be treated as a single argument, and Python would raise a TypeError. Unpacking splits the dictionary into individual keyword arguments, which are then absorbed by **kwargs.

Example:


        def show_details(**kwargs):
            for k, v in kwargs.items():
                print(f"{k} = {v}")

        user_data = {"name": "Alice", "age": 28}
        show_details(**user_data)