Variable-Length Arguments (*args, **kwargs)
When building functions, you often know exactly how many arguments they need. But what if a function needs to handle an unspecified number of inputs? Consider a logging utility that might take one message or several, or a configuration function that accepts arbitrary settings. Python provides args and kwargs to address this, allowing functions to accept a flexible number of positional and keyword arguments, respectively.
Collecting Positional Arguments with args
The args syntax in a function definition allows a function to accept an arbitrary number of positional arguments. When the function is called, all positional arguments that are not explicitly matched to named parameters are collected into a tuple. This tuple is then assigned to the args variable (or whatever name you choose after the ). It's particularly useful when you need to perform an operation on a collection of similar inputs without knowing their exact count beforehand.
While args is the conventional name, you can use any valid variable name after the (e.g., items, values). However, args is widely recognized and improves code readability.
Unpacking Sequences with During Function Calls
The operator has a dual role. Besides collecting arguments in a function definition, it can also be used when calling a function to unpack an iterable (like a list or tuple) into individual positional arguments. This is incredibly useful when you have a collection of values and want to pass them to a function that expects multiple distinct positional arguments, or even a function defined with args.
args collects arguments into a tuple, what happens if you pass a list directly without when the function expects args?Collecting Keyword Arguments with **kwargs
Similar to args, the kwargs syntax in a function definition allows a function to accept an arbitrary number of keyword arguments. When the function is called, all keyword arguments that are not explicitly matched to named parameters are collected into a dictionary. The keys of this dictionary are the argument names (strings), and the values are their corresponding argument values. This is ideal for functions that need to handle flexible configuration options or pass settings to other functions.
Similar to args, kwargs is a convention. You can use any valid variable name after (e.g., options, config). However, kwargs is the standard and should be preferred for clarity.
Unpacking Dictionaries with During Function Calls
Just as unpacks iterables for positional arguments, the operator can be used when calling a function to unpack a dictionary into individual keyword arguments. This is extremely useful when you have configuration stored in a dictionary and want to pass those key-value pairs directly as keyword arguments to a function. It saves you from manually writing out each key=value pair.
Argument Order: Positional, args, Keyword, kwargs
When defining a function that uses a combination of standard arguments, args, and kwargs, Python enforces a strict order. The parameters must appear in this sequence: normal positional arguments, followed by args, then keyword-only arguments (if any), and finally kwargs. Deviating from this order will result in a SyntaxError. This structure ensures clarity on how arguments are matched and collected.
Placing args after a keyword-only argument (e.g., def func(a, kwarg=1, args):) or **kwargs before args will result in a SyntaxError. Python needs to know which arguments are positional and which are keyword-based to correctly parse the function definition.
Practical Use Cases: Building Flexible APIs
The primary benefit of args and kwargs is to create highly flexible function interfaces. This is particularly valuable when writing wrapper functions, decorators, or functions that need to pass arguments through to another underlying function without knowing its exact signature. It allows you to build generic utilities that adapt to various inputs, making your code more reusable and robust.
timed_logger decorator to also include the current timestamp in the log messages. Add a new log_level keyword argument to the wrapper function, defaulting to 'INFO', and print it in the log message.Edge Cases and Argument Precedence
When using args and kwargs, it's important to understand how arguments are resolved. If a function has both named parameters and args/kwargs, the named parameters take precedence. Any argument explicitly passed by name will match a named parameter first. If a keyword argument is passed that matches a key in a dictionary being unpacked by , the explicitly passed argument will override the value from the unpacked dictionary. This behavior allows for default values from dictionaries to be easily customized.
(arg1, args, kwargs) and you call it with func(1, 2, a=3, b=4)?args and kwargs| Feature | args (Positional Arguments) | **kwargs (Keyword Arguments) |
|---|---|---|
| Purpose | Collects an arbitrary number of positional arguments. | Collects an arbitrary number of keyword arguments. |
| Data Type Collected | A tuple of arguments. | A dictionary of argument names (keys) and values. |
| Syntax in Definition | parameter_name (e.g., args) | parameter_name (e.g., kwargs) |
| Syntax in Call (Unpacking) | iterable (e.g., my_list) to unpack a sequence into positional arguments. | dictionary (e.g., my_dict) to unpack a dictionary into keyword arguments. |
| When to Use | When a function needs to operate on a variable number of unnamed inputs (e.g., sum(), print()). | When a function needs to accept flexible configuration options or pass settings (e.g., plot(), requests.get()). |
args and kwargs to clarify their distinct roles.argscollects an arbitrary number of positional arguments into atuplewithin a function.kwargscollects an arbitrary number of keyword arguments into adictionarywithin a function.The operator can unpack iterables (lists, tuples) into individual positional arguments when calling a function.
The
operator can unpack dictionaries into individual keyword arguments when calling a function.Function parameters must follow a strict order: normal positional,
args, keyword-only, thenkwargs.Explicitly passed keyword arguments always override values provided by dictionary unpacking using .
Use
argsandkwargsto design flexible, reusable functions, especially for wrappers or argument passthrough.