Getting defaults wrong either raises at class creation or shares one list between all instances.
Fields can have default values: retries: int = 3. Fields with defaults become optional constructor parameters, and they must come after fields without defaults, just like function parameters. Otherwise you get TypeError: non-default argument 'b' follows default argument when the class is created.
Mutable defaults are a classic Python trap: a default list in a function signature is shared across calls. Dataclasses protect you: tags: list[str] = [] raises ValueError: mutable default <class 'list'> for field tags is not allowed: use default_factory. The check rejects any default that is unhashable, which covers list, dict and set.
The fix is field(default_factory=...), a zero-argument callable called for each new instance:
tags: list[str] = field(default_factory=list)
created: datetime = field(default_factory=datetime.now)Any callable works: list, dict, a lambda, or a function returning a fresh default config.
Default values are also stored as class attributes, so Config.retries is 3. Fields using default_factory have no class attribute.
Keyword-only fields (a later lesson) relax the ordering rule.
Example
from dataclasses import dataclass, field
from datetime import datetime
@dataclass
class Task:
title: str
priority: int = 3
tags: list[str] = field(default_factory=list)
created: datetime = field(default_factory=datetime.now)
a, b = Task("write docs"), Task("fix bug", priority=1)
a.tags.append("docs")
print(a.tags, b.tags) # ['docs'] [] (separate lists)
print(b.priority, Task.priority) # 1 3
try:
@dataclass
class Bad:
items: list[int] = []
except ValueError as e:
print(e) # mutable default <class 'list'> for field items is not allowed: use default_factoryRemember
- Fields with defaults must follow fields without
- Mutable defaults like [] are rejected
- field(default_factory=list) creates a fresh value per instance
Watch out for
- Using a mutable custom object as a default; it is shared unless it is unhashable and rejected.