How to Use *args and **kwargs in Python Functions

Master *args and **kwargs in Python. Learn how to write flexible functions with dynamic positional and keyword arguments, unpack collections, and build wrapper functions.

Try Code in Editor

Explanation

In Python, you will often need to design functions that can accept a variable number of arguments. For example, a function that calculates the sum of any number of integers, or a function that logs metadata with varying fields. Instead of forcing users to pass a list or dictionary, Python provides two special symbols: `*args` and `**kwargs`.

The `*args` syntax allows a function to accept any number of positional arguments. The single asterisk `*` acts as an unpacking operator. When placed in a function definition, it collects extra positional arguments into a tuple named `args`. This lets you iterate over the input values, run computations, or pass them along to another function with ease.

The `**kwargs` syntax, on the other hand, allows a function to accept any number of keyword (named) arguments. The double asterisk `**` collects these arguments into a dictionary named `kwargs`. This is incredibly useful for passing optional configurations, styling arguments, or database attributes. Remember, the names 'args' and 'kwargs' are conventions; the actual functionality is driven by the single and double asterisks.

Step-by-Step Implementation

  1. 1

    Use a single asterisk before a parameter (e.g., *args) to gather positional arguments into a tuple.

  2. 2

    Use a double asterisk before a parameter (e.g., **kwargs) to gather keyword arguments into a dictionary.

  3. 3

    Maintain the correct parameter order: standard parameters, *args, keyword-only parameters, then **kwargs.

  4. 4

    Use unpacking syntax when calling functions by passing *iterable or **dictionary.

Code Example

This code demonstrates using *args to sum variable numbers, **kwargs to print user profiles, and combining both in a single function.

args_kwargs.py
Try in Editor
def sum_all(*args):
    print("args type:", type(args).__name__)
    return sum(args)

print("Sum (1, 2, 3):", sum_all(1, 2, 3))
print("Sum (10, 20):", sum_all(10, 20))

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

print_profile(name="Bob", role="developer", country="US")

def master_function(first, *args, **kwargs):
    print(f"First argument: {first}")
    print(f"Additional positional args: {args}")
    print(f"Keyword args: {kwargs}")

master_function("hello", 1, 2, 3, debug=True, user_id=42)
Terminal Output
args type: tuple
Sum (1, 2, 3): 6
args type: tuple
Sum (10, 20): 30
kwargs type: dict
name: Bob
role: developer
country: US
First argument: hello
Additional positional args: (1, 2, 3)
Keyword args: {'debug': True, 'user_id': 42}

Frequently Asked Questions

Do I have to use the names "args" and "kwargs"?

No, these are standard community conventions. Only the * and ** prefixes are syntactically required. You could write *values and **options, but sticking to *args and **kwargs is highly recommended for readability.

What is the correct ordering when defining a function?

The correct order of arguments in a function signature is: positional arguments, *args, keyword-only arguments, and finally **kwargs.

Related How-To Guides

Recommended Python Resources

Expand your knowledge with related interactive tutorials, cheat sheets, and code comparisons.