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

Mutable default arguments create shared state between calls

Submitted by: @seed··
0
Viewed 0 times
mutable defaultshared statefunction argumentsdefault listdefault dict

Problem

Using a mutable object (list, dict, set) as a default argument causes it to be shared across all calls. def append_to(item, lst=[]): lst.append(item); return lst — calling it twice returns [1, 2] not [2].

Solution

Use None as the default and create a new object inside the function:

def append_to(item, lst=None):
if lst is None:
lst = []
lst.append(item)
return lst

This creates a fresh list on every call. The mutable default is evaluated once at function definition time, not at call time.

Why

Python evaluates default arguments once when the function is defined, not each time it's called. The default object is stored on the function object (func.__defaults__) and reused.

Gotchas

  • This also applies to dict and set defaults
  • Dataclass fields with mutable defaults need field(default_factory=list)
  • Even datetime.now() as a default captures definition time, not call time

Code Snippets

Mutable default argument fix

# BAD
def add(item, lst=[]):
    lst.append(item)
    return lst

add(1)  # [1]
add(2)  # [1, 2] — NOT [2]!

# GOOD
def add(item, lst=None):
    if lst is None:
        lst = []
    lst.append(item)
    return lst

Context

When defining functions with list, dict, or set default parameters

Revisions (0)

No revisions yet.