序列化数据类列表:str 总是调用 repr
Serialising a list of dataclasses: str always calls repr
我想将数据类 序列化为字符串。使用 dataclasses.asdict
并创建自定义 __str__
方法就足够简单了。它工作得很好,即使 类 有其他数据 类 或它们的列表作为成员。但是,在数据列表 类 上调用 str
会生成 repr
版本。我希望 str
生成序列化表格并 repr
保持原样。
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))
上面脚本的输出是:
repr called
repr called
[{"i": 1}, {"i": 2}]
repr called
repr called
[{"i": 1}, {"i": 2}]
repr called
repr called
[{"i": 1}, {"i": 2}]
奇怪的是,str
方法中的 none 甚至在通过列表明确请求字符串版本时也会被调用。如果删除 repr=False
,repr
将被覆盖并调用自定义方法的 none。
想要的输出是:
>>> 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}]
list
的str
调用其元素的repr
,就是这样实现的。关于如何实现元素的 classes 不会改变这一点。因此,如果您不想干预数据 class 的 __repr__
,则必须使用您自己的集合 class 而不是 list
,例如:
class StrList(list):
def __str__(self):
return '[' + ', '.join(str(x) for x in self) + ']'
lst = StrList([1, '1'])
str(lst)
# '[1, 1]'
repr(lst)
# "[1, '1']"
如果你真的想改变像 list
这样的内置类型的 __str__
,你可以看看 forbiddenfruit
我想将数据类 序列化为字符串。使用 dataclasses.asdict
并创建自定义 __str__
方法就足够简单了。它工作得很好,即使 类 有其他数据 类 或它们的列表作为成员。但是,在数据列表 类 上调用 str
会生成 repr
版本。我希望 str
生成序列化表格并 repr
保持原样。
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))
上面脚本的输出是:
repr called
repr called
[{"i": 1}, {"i": 2}]
repr called
repr called
[{"i": 1}, {"i": 2}]
repr called
repr called
[{"i": 1}, {"i": 2}]
奇怪的是,str
方法中的 none 甚至在通过列表明确请求字符串版本时也会被调用。如果删除 repr=False
,repr
将被覆盖并调用自定义方法的 none。
想要的输出是:
>>> 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}]
list
的str
调用其元素的repr
,就是这样实现的。关于如何实现元素的 classes 不会改变这一点。因此,如果您不想干预数据 class 的 __repr__
,则必须使用您自己的集合 class 而不是 list
,例如:
class StrList(list):
def __str__(self):
return '[' + ', '.join(str(x) for x in self) + ']'
lst = StrList([1, '1'])
str(lst)
# '[1, 1]'
repr(lst)
# "[1, '1']"
如果你真的想改变像 list
这样的内置类型的 __str__
,你可以看看 forbiddenfruit