Skip to content
Advertisement

dataclasses: how to ignore default values using asdict()?

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.

User contributions licensed under: CC BY-SA
3 People found this is helpful
Advertisement