When a parameter is prefixed with a single asterisk, Python gathers every remaining positional argument into a tuple bound to that name — the name args is just a convention, not a requirement. This is how built-ins like print() and max() accept any number of arguments. The same asterisk can also be used at a call site to unpack an existing list or tuple into separate positional arguments.
1Understanding Arguments (*args)
When a parameter is prefixed with a single asterisk, Python gathers every remaining positional argument into a tuple bound to that name — the name args is just a convention, not a requirement. This is how built-ins like print() and max() accept any number of arguments. The same asterisk can also be used at a call site to unpack an existing list or tuple into separate positional arguments.
Use a single asterisk at a call site to spread an existing list or tuple out into individual positional arguments, the mirror image of collecting them with *args in a function definition.
def total(*args):
return sum(args)
print(total(1, 2, 3, 4))2Practical Example
Here is a real-world application of **Arguments (*args)** showing how it is used in production Python code.
def log(level, *messages):
for msg in messages:
print(f"[{level}] {msg}")
log("INFO", "Started", "Connected", "Ready")3Best Practices
Follow these guidelines when working with **Arguments (*args)**:
1. Use *args when a function genuinely needs to accept an unknown, variable number of positional inputs
2. Prefer explicit, named parameters over *args when the function only ever expects a fixed, known set of arguments
3. Combine *args with regular named parameters, which must come before it, when some arguments are required and the rest are open-ended
Tip: Use a single asterisk at a call site to spread an existing list or tuple out into individual positional arguments, the mirror image of collecting them with *args in a function definition.
def total(*args):
return sum(args)
print(total(1, 2, 3, 4))