gotchaMajor
Python mutable default arguments sharing state between calls
Viewed 0 times
mutable defaultdefault argumentlist defaultshared stateNone patterndef
terminalnodejs
Error Messages
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 itemsRevisions (0)
No revisions yet.