I've started making heavy use of the python dataclasses module and find it very useful. I especially like the flags that can be set on each field allowing for toggling of compare, init etc.
I often find however that there is a field which I wish to omit from the asdict behaviour of the class. In some situations this may be possible with the dict_factory argument, but it sometimes happens that a field will cause the asdict function to raise an exception before it is omitted through use of the dict_factory.
Can anyone else suggest a clean way to do this? Would it not be a useful additional flag to add to the dataclasses module?
I've ended up defining dict_factory in dataclass as staticmethod and then using in as_dict(). Found it more straightforward than messing with metadata.
from typing import Optional, Tuple
from dataclasses import asdict, dataclass
@dataclass
class Space:
size: Optional[int] = None
dtype: Optional[str] = None
shape: Optional[Tuple[int]] = None
@staticmethod
def dict_factory(x):
exclude_fields = ("shape", )
return {k: v for (k, v) in x if ((v is not None) and (k not in exclude_fields))}
s1 = Space(size=2)
s1_dict = asdict(s1, dict_factory=Space.dict_factory)
print(s1_dict)
# {"size": 2}
s2 = Space(dtype='int', shape=(2, 5))
s2_dict = asdict(s2, dict_factory=Space.dict_factory)
print(s2_dict)
# {"dtype": "int"}
# no "shape" key, because it is excluded in dict_factory of the class.
You can add custom metadata to field like field(metadata={"include_in_dict":True}) and in the dict_factory you can check this before anything else and skip the field if needed.
if field_.metadata.get("include_in_dict", False):
continue
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With