I would like to ignore the default values after calling asdict()
@dataclass class A: a: str b: bool = True
so if I call
a = A("1") result = asdict(a, ignore_default=True) assert {"a": "1"} == result # the "b": True should be deleted
Advertisement
Answer
The dataclasses
module doesn’t appear to have support for detecting default values in asdict()
, however the dataclass-wizard
library does — via skip_defaults
argument.
Example:
from dataclasses import dataclass from dataclass_wizard import asdict @dataclass class A: a: str b: bool = True a = A("1") result = asdict(a, skip_defaults=True) assert {"a": "1"} == result # the "b": True should be deleted
Further, results show it is close to 2x faster than an approach with dataclasses.adict()
.
I’ve added benchmark code I used for testing below.
from dataclasses import dataclass, asdict as asdict_orig, MISSING from timeit import timeit from dataclass_wizard import asdict @dataclass class A: a: str b: bool = True def asdict_factory(cls): def factory(obj: list[tuple]) -> dict: d = {} for k, v in obj: field_value = cls.__dataclass_fields__[k].default if field_value is MISSING or field_value != v: d[k] = v return d return factory a = A("1") A_fact = asdict_factory(A) print('dataclass_wizard.asdict(): ', timeit('asdict(a, skip_defaults=True)', globals=globals())) print('dataclasses.asdict(): ', timeit('asdict_orig(a, dict_factory=A_fact)', globals=globals())) result1 = asdict(a, skip_defaults=True) result2 = asdict_orig(a, dict_factory=A_fact) assert {"a": "1"} == result1 == result2 a2 = A("1", True) a3 = A("1", False) assert asdict(a2, skip_defaults=True) == asdict_orig(a2, dict_factory=A_fact) assert asdict(a3, skip_defaults=True) == asdict_orig(a3, dict_factory=A_fact)
Disclaimer: I am the creator and maintainer of this library.