PythonFunctionsIntermediate

Keyword-only arguments

Forces some parameters to be passed by name for clarity and safety.

Review the syntaxStudy the examplesOpen the coding app
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

*marker · Everything after * must be passed as keyword args.
timeout (optional)float · Example keyword-only option.
retries (optional)int · Example keyword-only option.

See it in practice

Examples

1

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'))
Output:
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.

2

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'))
Output:
<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.

3

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)
Output:
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

1

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 TypeError
2

SyntaxError

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): pass

Runtime support

Compatibility

Python 3.8+

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.