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 post-init function is an in-built function in python and helps us to initialize a variable outside the __init__ function. post-init function in python.
Python introduced the dataclass in version 3.7 (PEP 557). The dataclass allows you to define classes with less code and more functionality out of the box. The following defines a regular Person class with two instance attributes name and age : class Person: def __init__(self, name, age): self.name = name self.age = age.
A data class is a class typically containing mainly data, although there aren't really any restrictions. It is created using the new @dataclass decorator, as follows: from dataclasses import dataclass @dataclass class DataClassCard: rank: str suit: str.
DataClass in Python DataClasses are like normal classes in Python, but they have some basic functions like instantiation, comparing, and printing the classes already implemented. Parameters: init: If true __init__() method will be generated. repr: If true __repr__() method will be generated.
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.
I know the question is about dataclass
, but if you're using attr.s
instead then you can use attr.evolve
instead of dataclasses.replace
:
import attr @attr.s(frozen=True) class Foo: x = attr.ib() y = attr.ib() foo = Foo(1, 2) bar = attr.evolve(foo, y=3)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With