*args and **kwargs in Python: What they are and How to use them

  

In Python, functions are extremely flexible. Sometimes, however, we don't know in advance how many arguments will be passed to a function. This is where *args and **kwargs come into play.

Let's look at them one by one, with simple and concrete examples.

🔗 Like Techelopment? Check out the website for all the details!

What is *args

*args allows a function to accept a variable number of positional arguments.

Basic example

def sum_all(*args):
    total = 0
    for number in args:
        total += number
    return total

print(sum_all(1, 2, 3))
print(sum_all(5, 10, 15, 20))

📌 Output:

6
50

In this case:

  • args is a tuple
  • it contains all the arguments passed to the function

👉 The name args is just a convention: you could also call it *numbers, but using args makes the code more readable for others.


Using *args with other parameters

*args can coexist with "normal" parameters, but it must come after them.

def greet(message, *names):
    for name in names:
        print(f"{message}, {name}!")

greet("Hello", "Luke", "Anna", "Mark")

What is **kwargs

**kwargs allows passing a variable number of keyword arguments to a function.

Basic example

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

print_info(name="Mario", age=30, city="Rome")

In this case:

  • kwargs is a dictionary
  • it contains key: value pairs

📌 Again, kwargs is a convention that stands for keyword arguments.


*args and **kwargs together

Both can be used in the same function. The correct order is:

  1. normal parameters
  2. *args
  3. **kwargs
def example(a, b, *args, **kwargs):
    print("a:", a)
    print("b:", b)
    print("args:", args)
    print("kwargs:", kwargs)

example(1, 2, 3, 4, x=10, y=20)

📌 Output:

a: 1
b: 2
args: (3, 4)
kwargs: {'x': 10, 'y': 20}

When to use *args and **kwargs

They are particularly useful when:

  • you are writing generic functions
  • you create decorators
  • working with APIs, libraries, or frameworks
  • you want to make the code more flexible and reusable

A typical example is argument forwarding:

def wrapper(*args, **kwargs):
    return original_function(*args, **kwargs)

Summary Table

Element Type of arguments Data structure When to use it Example
*args Positional Tuple When the number of arguments is not known in advance def f(*args):
**kwargs Named (keyword) Dictionary When you want to pass optional key-value pairs def f(**kwargs):
*args + **kwargs Positional and Named Tuple + Dictionary For flexible functions or wrappers/decorators def f(*args, **kwargs):

Be careful not to overdo it ⚠️

While powerful, using them everywhere can make the code:

  • less readable
  • harder to debug

👉 Use them only when they are truly needed.


Conclusion

  • *args collects positional arguments into a tuple
  • **kwargs collects named arguments into a dictionary
  • Together they make Python functions extremely flexible

If you are learning Python, understanding them well is a fundamental step to writing more elegant and professional code 🐍✨



Follow me #techelopment

Official site: www.techelopment.it
facebook: Techelopment
instagram: @techelopment
X: techelopment
Bluesky: @techelopment
telegram: @techelopment_channel
whatsapp: Techelopment
youtube: @techelopment