Chapters
Python114 chapters

FunctionsChapter 51 of 114

Default Values

Make a parameter optional, and avoid the shared-default trap.

Giving a parameter a default

Python
def greet(name, greeting="Hello"):
    print(f"{greeting}, {name}")

greet("Ada")
greet("Ada", "Good morning")
greet("Ada", greeting="Hi")

Output

Hello, Ada
Good morning, Ada
Hi, Ada

A default makes the parameter optional. The caller can ignore it entirely.

Defaults come last

Parameters with defaults must follow those without, because otherwise Python could not tell which one a positional argument meant:

Python
def greet(greeting="Hello", name):   # SyntaxError
    pass

Evaluated once, at definition time

This is the rule behind the most notorious Python gotcha. The default expression runs when def runs, not on each call:

Python
def add(item, target=[]):
    target.append(item)
    return target

print(add("a"))
print(add("b"))
print(add("c"))

Output

['a']
['a', 'b']
['a', 'b', 'c']

One list, created once, shared by every call. The same applies to dictionaries, sets and anything else mutable.

It also applies to values computed at definition time, which is why a timestamp default freezes at import:

Python
def stamp(when=None):
    if when is None:
        when = "computed at call time"
    return when

print(stamp())

Output

computed at call time

The fix

Use None as the default and build the real one inside:

Python
def add(item, target=None):
    if target is None:
        target = []
    target.append(item)
    return target

print(add("a"))
print(add("b"))

Output

['a']
['b']

Test with is None rather than truthiness. An empty list the caller deliberately passed is falsy, and if not target: would silently replace it:

Python
def add(item, target=None):
    if target is None:
        target = []
    target.append(item)
    return target

mine = []
add("a", mine)
print(mine)

Output

['a']

Immutable defaults are fine

Numbers, strings, True, False, None and tuples cannot be changed, so sharing them is harmless:

Python
def repeat(text, times=2, sep="-"):
    return sep.join([text] * times)

print(repeat("ab"))
print(repeat("ab", 3, "+"))

Output

ab-ab
ab+ab+ab

Defaults are visible

They are stored on the function object, which is occasionally useful and also shows plainly that they are computed once:

Python
def greet(name, greeting="Hello"):
    pass

print(greet.__defaults__)

Output

('Hello',)

Choosing good defaults

Pick the value the caller would have chosen most of the time, and make the dangerous option the one they have to ask for:

Python
def save(data, overwrite=False):
    return f"saving {data}, overwrite={overwrite}"

print(save("report"))
print(save("report", overwrite=True))

Output

saving report, overwrite=False
saving report, overwrite=True

Test yourself

2 questions

When is a default value evaluated?

Show the answer

Once, when the def runs — That single evaluation is exactly why a mutable default is shared between calls.

Why test 'if target is None' rather than 'if not target'?

Show the answer

An empty list the caller passed deliberately is falsy and would be replaced — Absence and emptiness are different questions, and only one of them means 'use the default'.

Next chapter

Return Values

Hand a result back, return several things, and leave early.