What does a bare asterisk do in a parameter list? What are keyword-only parameters?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
In a Python function signature, a bare * means "all parameters after this point must be passed by keyword". It does not collect arguments the way *args does. Instead, it acts as a divider between positional parameters and keyword-only parameters.
Keyword-only parameters are useful when an argument is clearer or safer when the caller names it explicitly. They make function calls more readable and reduce mistakes caused by ambiguous positional arguments.
What the Bare * Does
Consider this function:
This call works because host and port are positional-or-keyword parameters, while timeout and use_ssl are keyword-only. A positional call for those trailing arguments fails:
Python raises a TypeError because the bare * said that every parameter after it must be named.
That is the entire purpose of the bare asterisk. It introduces keyword-only parameters without collecting extra positional arguments.
How This Differs From *args
A signature with *args also makes later parameters keyword-only, but it does one extra thing: it captures additional positional arguments.
Here, values receives a tuple of positional arguments, and prefix is keyword-only because it appears after *values.
With a bare *, there is no tuple capture at all:
That form is what you use when you want keyword-only behavior but do not want to accept arbitrary extra positional values.
Why Keyword-Only Parameters Are Useful
Keyword-only parameters improve APIs when several trailing options are easy to mix up. For example, compare these two call styles:
That call is much clearer than:
When the reader sees named arguments, the meaning is obvious. This is especially valuable for boolean flags, optional tuning knobs, and parameters that are rarely used.
Keyword-only parameters can also be required. If you omit a default value, the caller must provide the name explicitly:
That is a clean way to force clarity for arguments that should never be passed positionally.
Think About API Design, Not Just Syntax
The bare * is most useful when function calls should read like small declarations. It is less about clever syntax and more about intentional API design.
A good rule of thumb is:
- keep the small required values positional if their order is obvious
- make optional flags and rare configuration settings keyword-only
This balances brevity with clarity. Too many keyword-only parameters on a tiny helper can feel heavy, but on public APIs they often make the call site much easier to understand.
Common Pitfalls
- Thinking the bare
*behaves like*args. It does not collect any values. - Forgetting that parameters after the bare
*can still be required if they have no default. - Using too many positional boolean flags instead of making them keyword-only.
- Adding keyword-only parameters to an existing public function without considering how that changes callers.
- Confusing the bare
*with/, which marks positional-only parameters and solves a different problem.
Summary
- A bare
*in a Python signature makes all following parameters keyword-only. - It is a separator, not a collector like
*args. - Keyword-only parameters improve readability and reduce mistakes at call sites.
- They are especially useful for optional flags and configuration values.
- If a keyword-only parameter has no default, the caller must provide it by name.

