![]() |
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.
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:
argsis 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:
kwargsis a dictionary- it contains
key: valuepairs
📌 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:
- normal parameters
*args**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
*argscollects positional arguments into a tuple**kwargscollects 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
