I'd like to serialise dataclasses to strings. That's easy enough with dataclasses.asdict
and creating a custom __str__
method. It works perfectly, even for classes that have other dataclasses or lists of them as members. However, calling str
on a list of dataclasses produces the repr
version. I'd like str
to produce the serialised form and repr
to stay as it is.
import json
from dataclasses import dataclass, asdict
@dataclass
class Ser:
def __repr__(self):
print('repr called')
return json.dumps(asdict(self))
def __str__(self):
print('str called')
return json.dumps(asdict(self))
@dataclass(repr=False)
class C(Ser):
i: int
def __str__(self):
print('child str called')
return super().__str__()
list_in = json.loads('[{"i": 1}, {"i": 2}]')
data = [C(**i) for i in list_in]
print(data)
print(repr(data))
print(str(data))
The output of the script above is:
repr called
repr called
[{"i": 1}, {"i": 2}]
repr called
repr called
[{"i": 1}, {"i": 2}]
repr called
repr called
[{"i": 1}, {"i": 2}]
Curiously, none of the str
methods are ever called even when explicitly asking for the string version through the list. If the repr=False
is removed, the repr
is overwritten and none of the custom methods are called.
The wanted output would be:
>>> data # I guess inspecting with the command line always calls repr
[C(i=1), C(i=2)]
>>> repr(data)
[C(i=1), C(i=2)]
>>> str(data)
[{"i": 1}, {"i": 2}]