What do args and kwargs mean?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
In Python, *args and **kwargs let a function accept a variable number of arguments. They are useful when the exact number of inputs is not fixed ahead of time, especially in wrappers, decorators, forwarding functions, and extensible APIs.
What *args Means
*args collects extra positional arguments into a tuple.
This prints:
The name args is only a convention. You could write *values or *items, but *args is the common style people expect to see.
The important part is the *, not the word args.
What **kwargs Means
**kwargs collects extra keyword arguments into a dictionary.
This prints something like:
Again, the name kwargs is conventional. The ** is what gives the parameter its behavior.
Using Both Together
A function can accept both kinds of variable arguments at the same time:
This is common in wrapper functions because they can accept almost anything and forward it elsewhere.
Why They Are Useful
The classic use case is writing a wrapper or decorator without hardcoding the wrapped function’s full parameter list.
Without *args and **kwargs, this kind of reusable wrapper would be much more awkward.
Definition Order Matters
Function parameter order in Python follows rules. In a definition, *args must come before **kwargs.
That order matters because Python needs to know which inputs are positional, which are keyword-only, and which belong in the flexible collections.
Unpacking at the Call Site
The same syntax also works in reverse when calling a function.
* unpacks a sequence into positional arguments:
** unpacks a dictionary into keyword arguments:
This is one reason the feature is so powerful. The same operators help both in function definitions and in function calls.
When Not to Use Them
Just because *args and **kwargs are flexible does not mean every function should use them.
If a function has a stable, well-known interface, explicit parameters are usually better:
This is easier to read, easier to type-check, and easier for IDEs to help with.
So a good rule is:
- use dynamic argument capture when flexibility is truly needed
- use explicit parameters when the API is known and stable
Common Pitfalls
The most common pitfall is thinking args and kwargs are special names. They are not. The stars are what matter.
Another mistake is overusing *args and **kwargs for ordinary application functions where explicit parameters would be much clearer.
A third issue is forwarding **kwargs blindly to another function that does not accept all those keys. That can create surprising runtime errors.
Finally, beginners sometimes forget the data types involved: *args becomes a tuple and **kwargs becomes a dictionary.
Summary
- '
*argscollects extra positional arguments into a tuple.' - '
**kwargscollects extra keyword arguments into a dictionary.' - They are especially useful for wrappers, decorators, and forwarding functions.
- The names
argsandkwargsare conventions; the stars are the real syntax. - Prefer explicit function signatures when the interface is stable and well known.

