dataclasses.replace constructs a new dataclass instance with selected fields changed; unchanged field values are passed through.
Python dataclasses.replace: a new record can retain old mutable fields
Operation contract
The original dispatch record owns a list of receipt IDs. Replacing its region gives a new record but keeps that same list object. Mutating the new record changes the old record’s receipt list too. The second replacement supplies an explicit copy and isolates later appends. A frozen dataclass would prevent rebinding a field, not mutation of a list held in it.
Failure and ownership boundary
Shallow copy semantics matter when records cross request, worker or cache boundaries. A list of nested mutable objects needs a deeper ownership policy. Python dataclasses: frozen fields require an immutable value model, Python shallow and deep copies: preserve aliases deliberately and Python variables: names refer to objects, assignment does not copy cover the surrounding rules.
Working program
from dataclasses import dataclass, replace
@dataclass
class DispatchBatch:
region: str
receipt_ids: list[str]
original = DispatchBatch("north", ["R41"])
shared = replace(original, region="east")
shared.receipt_ids.append("R42")
isolated = replace(original, region="west", receipt_ids=list(original.receipt_ids))
isolated.receipt_ids.append("R43")
print(original.receipt_ids)
print(isolated.receipt_ids)
print(shared.receipt_ids is original.receipt_ids)Output
['R41', 'R42']
['R41', 'R42', 'R43']
TrueCosts and limits
The replacement itself has bounded field work. Copying n IDs takes O(n) time and O(n) outer storage; nested objects would remain shared.
Common Mistakes
- A new dataclass instance is not a deep snapshot.
- Frozen fields do not freeze mutable values.
Connected lessons
Python dataclasses: frozen fields require an immutable value model, Python shallow and deep copies: preserve aliases deliberately, Python variables: names refer to objects, assignment does not copy.
