๐ Python dataclasses: the list that wanted roommates
You create two objects. You update the list in one. Somehow, the other object knows about it.
Congratulations: your objects are sharing. Unfortunately, nobody asked them to.
๐ง The tiny trap
Python’s ordinary class attributes can be shared between instances. Dataclasses protect against many mutable-default mistakes by rejecting unhashable defaults, including a plain list, in current Python versions.
So this raises a ValueError:
from dataclasses import dataclass
@dataclassclassTask:
tags: list[str] = []
๐ง The fix
Let each instance create its own list:
from dataclasses import dataclass, field
@dataclassclassTask:
tags: list[str] = field(default_factory=list)
default_factory calls the supplied zero-argument function when a default is needed. Here, list creates a fresh list for each instance.
๐ญ My take
If a dataclass owns a list or dictionary, default_factory is my default reflex. Pun mildly intended.
It’s explicit, readable, and saves the next developer from wondering why Task A knows Task B’s secrets.
One nuance: this is about creating a fresh container. It doesn’t magically deep-copy objects you later put inside that container.