How do I define a function with optional arguments?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Optional arguments let one function handle both the common case and a more configurable case without forcing every caller to supply every parameter. In Python, the standard mechanism is default parameter values, but there are a few related patterns that matter if you want the function to stay readable and bug-free.
Use Default Values in the Signature
An argument becomes optional when you give it a default value.
This is the core rule. If the caller omits punctuation, Python uses "!".
Required parameters must come first. Optional parameters with defaults come after them:
This ordering is invalid:
Prefer Named Calls for Optional Settings
Once a function has more than one optional flag, keyword arguments make the call site much easier to understand.
Compare that second call with a positional version such as create_user("mark", False, False, "fr"). The keyword version is far easier to read.
Use Keyword-Only Optional Arguments When Clarity Matters
If you want to prevent callers from passing certain optional arguments positionally, add * in the function signature.
Now overwrite and compress must be passed by name. This is a good pattern for configuration flags that would otherwise be ambiguous at the call site.
Avoid Mutable Default Values
The most important trap with optional arguments in Python is that default values are evaluated once, when the function is defined. So mutable defaults are reused across later calls.
Bad example:
That reuses the same list over time. The safe pattern is to use None as a sentinel and allocate inside the function.
This pattern also applies to dictionaries, sets, timestamps, and any other value that should be freshly created for each call.
Optional Arguments Versus *args and **kwargs
Sometimes developers mix up optional arguments with *args and **kwargs. They solve different problems.
- default values define known optional parameters
- '
*argscollects extra positional arguments' - '
**kwargscollects extra named arguments'
Example:
This is useful when the function truly accepts variable extra data. If the set of options is known ahead of time, normal named parameters are usually clearer.
Optional Arguments Can Improve API Design
Good optional parameters make a function easy to use in the common case and flexible in the uncommon case. Bad optional parameters create a giant function with too many loosely related flags.
A reasonable function:
A less healthy design is a function with many unrelated booleans and magic defaults that callers struggle to remember. In those cases, two smaller functions or a configuration object may be cleaner.
Common Pitfalls
The biggest pitfall is using mutable defaults such as [] or dict(). Another is overusing positional calls for optional settings, which makes function calls hard to read and easy to break. Developers also sometimes use **kwargs for everything when explicit named parameters would have been clearer. Finally, remember that defaults are evaluated once at definition time, so dynamic values such as the current time should be created inside the function body, not in the signature.
Summary
- Define optional arguments by assigning default values in the function signature.
- Put required parameters before optional ones.
- Prefer keyword arguments for readability when several optional settings exist.
- Use keyword-only parameters with
*when callers should name specific options. - Use
Noneinstead of mutable objects for safe dynamic defaults. - Use
*argsand**kwargsonly when the function truly needs flexible extra input.

