Use default factory to initialize nested dataclass fields
A quick take on how to avoid problems with nested dataclasses
I you happen to work with nested Python dataclasses , then maybe you’ve noticed an issues with defining field values by creating an instance of some object.
In the example below, all instances of class Main
will point to the same instance
of class Sub
:
from dataclasses import dataclass, field
@dataclass
class Sub:
prop: str = field(default="some value")
@dataclass
class Main:
sub: Sub = Sub()
m1 = Main()
m2 = Main()
id(m1)
Out[1]: 140304747921264
id(m2)
Out[2]: 140304748528400
assert id(m1.sub) != id(m2.sub)
---------------------------------------------------------------------------
AssertionError Traceback (most recent call last)
<ipython-input-8-63c2e0b3d3f5> in <module>
----> 1 assert id(m1.sub) != id(m2.sub)
AssertionError:
The fix is really easy. Simply provide the name of the class you want to instantiate as
default_factory
argument to the field
function:
from dataclasses import dataclass, field
@dataclass
class Sub:
prop1: str = field(default="some value")
@dataclass
class Main:
sub: Sub = field(default_factory=Sub)
m1 = Main()
m2 = Main()
assert id(m1.sub) != id(m2.sub)
This way you’ll correctly initialize field values.