Dynamically add fields to dataclass objects Dynamically add fields to dataclass objects python-3.x python-3.x

Dynamically add fields to dataclass objects


You could use make_dataclass to create X on the fly:

X = make_dataclass('X', [('i', int), ('s', str)])x = X(i=42, s='text')asdict(x)# {'i': 42, 's': 'text'}

Or as a derived class:

@dataclassclass X:    i: intx = X(i=42)x.__class__ = make_dataclass('Y', fields=[('s', str)], bases=(X,))x.s = 'text'asdict(x)# {'i': 42, 's': 'text'}


As mentioned, fields marked as optional should resolve the issue. If not, consider using properties in dataclasses. Yep, regular properties should work well enough - though you'll have to declare field in __post_init__, and that's slightly inconvenient.

If you want to set a default value for the property so accessing getter immediately after creating the object works fine, and if you also want to be able to set a default value via constructor, you can make use of a concept called field properties; a couple libraries like dataclass-wizard providefull support for that.

example usage:

from dataclasses import asdict, dataclassfrom typing import Optionalfrom dataclass_wizard import property_wizard@dataclassclass X(metaclass=property_wizard):    i: int    s: Optional[str] = None    @property    def _s(self):        return self._s    @_s.setter    def _s(self, s: str):        self._s = sx = X(i=42)x.s = 'text'x# X(i=42, s='text')x.s# 'text'asdict(x)# {'i': 42, 's': 'text'}

Disclaimer: I am the creator (and maintener) of this library.