Codectionary / Developer documentation / Python

Positional-only and keyword-only parameters

Make function call conventions explicit using / and * in parameter lists.

How it works

Parameters before / are positional-only. Parameters after a bare * are keyword-only. Parameters between those markers can be supplied either way. These markers are part of a definition, not values passed by callers.

A default controls whether an argument may be omitted; parameter kind controls how a supplied argument is written. Those are separate decisions. The / definition syntax requires Python 3.8 or later.

Choices and common mistakes

Use keyword-only parameters to make optional switches understandable at the call site. Avoid needlessly restrictive signatures in tiny private helpers.

An invalid call raises TypeError before the function body runs. Do not catch all TypeError exceptions around a large block just to detect one invalid call.

Try it yourself

Define a conversion function with positional-only amount and keyword-only rate. Try both valid and invalid calls and identify which rule each violates.

Syntax

def format_value(value, /, *, prefix=""):
    return prefix + str(value)

Examples

Name a formatting option

Make the purpose of a Boolean option visible.

def title(text, *, uppercase=False):
    return text.upper() if uppercase else text

print(title("Report", uppercase=True))
  1. The bare star makes uppercase keyword-only. The call spells out its meaning instead of using an unexplained positional True.
  2. The conditional expression selects upper() only when the flag is true. The unchanged text is the default result.
  3. Use named options for formatting or export functions with several optional settings.
  4. Expected output: REPORT

Require a positional value

Demonstrate a positional-only API boundary.

def double(value, /):
    return value * 2

print(double(4))
try:
    double(value=4)
except TypeError:
    print("Pass the value positionally")
  1. The slash prevents callers from binding value by name. The first call succeeds; the second fails before multiplication.
  2. The handler surrounds only the intentionally invalid call, so an unrelated error is not hidden.
  3. Positional-only parameters can let library authors change internal parameter names without breaking keyword callers.
  4. Expected output: 8 Pass the value positionally

Combine all three kinds

Separate the main value, a flexible unit and a named precision.

def measurement(value, /, unit="m", *, decimals=1):
    return f"{value:.{decimals}f} {unit}"

print(measurement(2.345, "cm", decimals=2))
  1. value must be positional, unit accepts either style, and decimals must be named.
  2. The nested format field uses decimals as the fixed-point precision. Formatting rounds the displayed representation, not the stored value.
  3. A measurement formatter benefits from an explicit precision option rather than several ambiguous positional numbers.
  4. Expected output: 2.35 cm

Best practices

  • Use keyword-only parameters to make optional switches understandable at the call site. Avoid needlessly restrictive signatures in tiny private helpers.
  • An invalid call raises TypeError before the function body runs. Do not catch all TypeError exceptions around a large block just to detect one invalid call.

Runtime & versions

Python interpreter. Feature availability depends on the language and runtime version used by your project; consult the official reference below.

Python language reference

Specifications & further reading