gotchapythonMajorpending
Gotcha: Python mutable default arguments in class methods
Viewed 0 times
mutable defaultshared statedefault argumentclass instanceslist default
Error Messages
Problem
Class instances share mutable default arguments, causing unexpected data sharing between instances.
Solution
Never use mutable defaults in function/method signatures:
# BUG: All instances share the same list!
class EventEmitter:
def __init__(self, listeners=[]): # Shared!
self.listeners = listeners
a = EventEmitter()
b = EventEmitter()
a.listeners.append('click')
print(b.listeners) # ['click'] - BUG!
# FIX: Use None and create in body
class EventEmitter:
def __init__(self, listeners=None):
self.listeners = listeners if listeners is not None else []
# Or with dataclass
from dataclasses import dataclass, field
@dataclass
class EventEmitter:
listeners: list = field(default_factory=list) # New list per instance
# Same issue with dicts, sets, and any mutable type:
# BAD
def add_item(item, cache={}):
cache[item.id] = item # Persists between calls!
return cache
# GOOD
def add_item(item, cache=None):
if cache is None:
cache = {}
cache[item.id] = item
return cacheWhy
Default arguments are evaluated ONCE at function definition time, not at each call. The same mutable object is reused across all calls/instances.
Context
Python classes and functions with collection defaults
Revisions (0)
No revisions yet.