runtime
72 / 250
lesson 72 Advanced Functions & Recursion · intermediate

Options that must be named

Parameters after a bare `*` can only be passed by name. Calls like `convert(100, rate=0.92)` stay readable, and a mixed-up argument order becomes an error instead of a wrong answer.

You'll be able to
  • Write def f(data, *, option) so option must be passed by name
  • Combine keyword-only parameters with defaults
  • Read the TypeError a positional call produces
The idea

Compare export(rows, True, False) with export(rows, header=True, overwrite=False). The first call is a puzzle: which True is which? And if someone swaps them, the program silently does the wrong thing.

A bare * in the parameter list says: everything after this must be passed by name. It collects nothing; it only draws the line.

Run each example to see what it prints. Running examples doesn't count toward progress.

example-1.py · A rate passed by position
def convert(amount, *, rate):
    return amount * rate

print(convert(100, 0.92))
example-2.py · Currency conversion with a named rate
def convert(amount, *, rate, fee=0):
    return amount * rate - fee

print(convert(100, rate=0.92))
print(convert(100, rate=0.92, fee=1.5))
print(convert(100, fee=1.5, rate=0.92))

Keyword-only parameters suit settings: numbers that would be easy to mix up when they sit side by side. A retry schedule is a good example. After a failed request, a client waits base, then twice that, then four times that, never longer than cap. Three numbers in a row would be easy to swap; named, they are self-explaining.

example-3.py · Retry delays, every setting named
def backoff_delays(*, attempts, base, cap):
    return [min(base * 2 ** i, cap) for i in range(attempts)]

print(backoff_delays(attempts=5, base=1, cap=10))
print(backoff_delays(attempts=3, base=0.5, cap=60))

When to use it: flags (dry_run=True), and settings of the same type that could be confused (attempts, base, cap). Keep the main data positional: convert(100, rate=…) reads naturally. Mistakes to avoid: writing *args when you only wanted the dividing line (that would also swallow extra positional arguments silently), and putting a keyword-only parameter without a default where most calls want the same value.

Review
  • Parameters after a bare * must be passed by name; a positional call raises TypeError.
  • Use keyword-only parameters for flags and for settings that could be mixed up.
  • Keyword-only parameters can have defaults, and named arguments can come in any order.
  • Next: lambda, a short function written right where it is passed.
Practise this

Loading your progress…

To master this lesson, solve both challenges without hints or the answer, and pass the concept check.

Options that must be named — Advanced Functions & Recursion · Runtime