`*args` and `**kwargs` — Flexible Function Arguments

Published:
Last updated:
By Jeferson Peter
Python

Sometimes, when defining functions, we don’t know exactly how many arguments will be passed.
In Python, *args and **kwargs solve this problem by allowing flexible functions that can handle different numbers of inputs.


Using *args

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

print(add(1, 2, 3))
print(add(10, 20))

# 6
# 30

➡️ Here, all extra positional arguments are packed into a tuple.


Using **kwargs

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

greet(name="Alice", age=25)

# name = Alice
# age = 25

➡️ In this case, the named arguments are stored in a dictionary.


Mixing both

def demo(*args, **kwargs):
    print("args:", args)
    print("kwargs:", kwargs)

demo(1, 2, 3, name="Bob", job="Dev")

# args: (1, 2, 3)
# kwargs: {'name': 'Bob', 'job': 'Dev'}

➡️ The function accepts any number of arguments, automatically organizing them into tuples and dictionaries.


Conclusion

  • *args collects extra positional arguments into a tuple.
  • **kwargs collects extra keyword arguments into a dictionary.

Together, they make your functions more flexible and reusable — especially useful in decorators, APIs, and libraries.