I'd like to create a copy of an existing instance of a dataclass and modify it.
Suppose we have a dataclass and an instance of that dataclass:
from dataclasses import dataclass, field, InitVar, replace
@dataclass
class D:
a: float = 10. # Normal attribute with a default value
b: InitVar[float] = 20. # init-only attribute with a default value
c: float = field(init=False) # an attribute that will be defined in __post_init__
def __post_init__(self, b):
self.c = self.a + b
d1 = D()
Let's define an instance and try to make a copy (I've tried solutions proposed in this post):
- Using the
replace
method:
d2 = replace(d1, **{})
throws an error
InitVar 'b' must be specified with replace()
It seems to be a reported bug, but I am not sure if there is any progress on it.
- By creating a new object from
__dict__
of an old object:
d2 = D(**d1.__dict__)
throws an error
__init__() got an unexpected keyword argument 'c'
Do you have any suggestions on how to copy dataclass instance properly or "workaround" indicated issues?
Edit:
- Fixed the bug in the initial code (
self.b
in__post_init__
)
I've made this workaround which seems to be working (posted in answers). If someone can find drawbacks it will be very appreciated.