I'd like to replace the attributes of a dataclass instance, analogous to namedtuple._replace()
, i.e. making an altered copy of the original object:
from dataclasses import dataclass
from collections import namedtuple
U = namedtuple("U", "x")
@dataclass
class V:
x: int
u = U(x=1)
u_ = u._replace(x=-1)
v = V(x=1)
print(u)
print(u_)
print(v)
This returns:
U(x=1)
U(x=-1)
V(x=1)
How can I mimic this functionality in dataclass objects?
The dataclasses
module has a helper function for field replacement on instances (docs)
from dataclasses import replace
Usage differs from collections.namedtuple
, where the functionality was provided by a method on the generated type (Side note: namedtuple._replace
is documented/public API, using an underscore on the name was called a "regret" by the author, see link at end of answer).
>>> from dataclasses import dataclass, replace
>>> @dataclass
... class V:
... x: int
... y: int
...
>>> v = V(1, 2)
>>> v_ = replace(v, y=42)
>>> v
V(x=1, y=2)
>>> v_
V(x=1, y=42)
For more background of the design, see the PyCon 2018 talk - Dataclasses: The code generator to end all code generators. The replace
API is discussed in depth, along with other design differences between namedtuple
and dataclasses
, and some performance comparisons are shown.