copy.replace
One spelling for what used to be namedtuple._replace, dataclasses.replace and datetime.replace. It simply calls type(obj).__replace__(obj, **changes) — types without that method get a TypeError.
Demo
import copy from collections import namedtuple Point = namedtuple('Point', 'x y') p = Point(1, 2) (p, copy.replace(p, x=5))
Each call returns a NEW object and leaves the original as it was: (Point(x=1, y=2), Point(x=5, y=2)). For the named tuple an unknown field gives TypeError: Got unexpected field names: ['z'] — the message comes from namedtuple._replace. A dataclass reports unknown names differently, as an unexpected keyword argument of __init__.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| obj | object | yes | An instance whose class defines __replace__: a namedtuple, a dataclass, date/datetime/time, SimpleNamespace … Positional only. |
| **changes | any | no | field=value pairs. Unknown names raise TypeError (the exact message comes from the type). |
Return value
same type as obj — A new object with the given fields replaced; obj is unchanged.
Common patterns
import copy test_config = copy.replace(prod_config, debug=True, db_url="sqlite://")
class Money: def __init__(self, amount, currency): self.amount, self.currency = amount, currency def __replace__(self, /, **changes): return Money(changes.get("amount", self.amount), changes.get("currency", self.currency))
import dataclasses p2 = p._replace(x=5) # namedtuple item2 = dataclasses.replace(item, qty=3) # dataclass
Examples
Pitfalls
from dataclasses import dataclass @dataclass(frozen=True) class Item: name: str qty: int = 1 item = Item("pen") item.qty = 3
import copy from dataclasses import dataclass @dataclass(frozen=True) class Item: name: str qty: int = 1 item = Item("pen") copy.replace(item, qty=3)
import copy copy.replace({'a': 1}, a=2)
{'a': 1} | {'a': 2}
When to use
- Deriving modified versions of immutable records (namedtuple, frozen dataclass)
- Generic code that should work for any type with __replace__
- Python 3.12 or older → _replace() / dataclasses.replace()
- Mutable objects you may change in place → just assign the attribute
- Plain dicts → {**d, "key": value} or d | {...}
Notes
FAQ
It returns a new object of the same type with the given fields changed, by calling the type’s __replace__ method. Named tuples, dataclasses, date/datetime/time and SimpleNamespace support it out of the box.