Keyword-only arguments
Forces some parameters to be passed by name for clarity and safety.
def f(a, *, timeout=1.0, retries=3):
...This static page keeps the syntax and examples indexed for search, while the coding app handles interactive exploration and saved references.
What it does
Overview
Forces some parameters to be passed by name for clarity and safety.
Keyword-only arguments, introduced in PEP 3102, are parameters that can only be supplied via keyword (key=value) rather than by position. They are defined by placing a bare asterisk '*' in the parameter list or by following a variadic '*args' parameter. This mechanism is crucial for API design as it allows developers to add new parameters without breaking positional argument order in existing calls. From a performance perspective, Python's bytecode includes specific checks for keyword-only arguments; while dictionary lookups for keywords are slightly slower than positional indexing, the difference is negligible compared to the gains in code safety. An important edge case is that keyword-only arguments must appear before '**kwargs' in the function signature. Using them prevents the 'boolean trap,' where multiple true/false flags are passed without context, making the code more readable and self-documenting.
Quick reference
Syntax
def f(a, *, timeout=1.0, retries=3):
...
Inputs
Parameters
See it in practice
Examples
Basic Keyword-Only Enforcement
def connect(*, host='localhost', port=3306):
return f'Connecting to {host}:{port}'
try:
print(connect('127.0.0.1'))
except TypeError as e:
print(f'Error: {e}')
print(connect(host='127.0.0.1'))Error: connect() takes 0 positional arguments but 1 was given Connecting to 127.0.0.1:3306
The '*' forces all subsequent arguments to be named, preventing the caller from passing '127.0.0.1' positionally.
Combining with Positional and Variadic Arguments
def tag(name, *content, cls=None):
return f'<{name} class="{cls}">{content}</{name}>'
# 'cls' can only be set via keyword because it follows *content
print(tag('p', 'Hello', 'World', cls='main'))<p class="main">('Hello', 'World')</p>
Arguments following a variadic *args parameter are automatically keyword-only. This allows the function to accept any number of positional elements while still offering specific configuration options.
Preventing Boolean Traps
def update_user(user_id, *, notify_user=False, admin_override=False):
pass
# Clear and self-documenting call
update_user(101, notify_user=True, admin_override=True)None
Forcing keywords for boolean flags ensures that the intent of 'True' or 'False' is immediately visible in the calling code.
Debug faster
Common Errors
TypeError
Cause: Attempting to pass a keyword-only argument as a positional argument.
Fix: Always provide the parameter name explicitly when calling the function.
def f(*, x): pass
f(10) # Raises TypeErrorSyntaxError
Cause: Defining positional arguments after the '*' separator or after keyword-only arguments.
Fix: Ensure that the '*' or '*args' comes after all standard positional arguments, but before any keyword-only arguments.
def f(*, x, y=1, z): pass # Valid
# def f(x, *, y, z=1, a): pass # Valid
# def f(*, x, y, z): passRuntime support
Compatibility
Source: MDN Web Docs
Common questions
Frequently Asked Questions
Forces some parameters to be passed by name for clarity and safety.
*: Everything after * must be passed as keyword args. timeout: Example keyword-only option. retries: Example keyword-only option.
TypeError: Always provide the parameter name explicitly when calling the function. SyntaxError: Ensure that the '*' or '*args' comes after all standard positional arguments, but before any keyword-only arguments.