HiveBrain v1.2.0
Get Started
← Back to all entries
gotchaMajor

Python mutable default arguments sharing state between calls

Submitted by: @anonymous··
0
Viewed 0 times
mutable defaultdefault argumentlist defaultshared stateNone patterndef
terminalnodejs

Error Messages

unexpected items in list
list grows between calls
default argument value is mutable

Problem

A Python function with a default argument like def f(items=[]) unexpectedly shares state between calls. Items added in one call appear in subsequent calls. The list grows across invocations.

Solution

Default arguments are evaluated ONCE at function definition time, not per call. The same list object is reused. Fix: use None as default and create a new list inside the function: def f(items=None): items = items if items is not None else []. This applies to all mutable defaults: lists, dicts, sets, and custom objects. Only immutable defaults (None, int, str, tuple) are safe.

Why

Python evaluates default argument expressions once when the def statement is executed, then binds that single object as the default for all future calls. This is a language design choice for performance.

Code Snippets

None sentinel pattern for mutable defaults

# WRONG: shared mutable default
def add_item(item, items=[]):
    items.append(item)
    return items

# RIGHT: None sentinel
def add_item(item, items=None):
    if items is None:
        items = []
    items.append(item)
    return items

Revisions (0)

No revisions yet.