【发布时间】:2019-06-04 21:55:32
【问题描述】:
我有一个要序列化的 Python 对象树。它的结构是这样的:
{
"regular_object": {
...
},
"regular_field": ...
"special_object": {
"f1": "v1",
"f2": v2,
...
"fn": "vn"
}
}
我想序列化这样的对象树,以便在 JSON 表示中像这样格式化:
{
"regular_object": {
...
},
"regular_field": ...
"special_object": { "f1": "v1", "f2": v2, ..., "fn": "vn" }
}
换句话说,我想要基于被格式化对象的内容的混合格式。
我尝试通过覆盖default 方法并使用自定义类对象来存储special_object 的内容来使用json.JSONEncoder,以便调用自定义default,如下所示:
class SpecialObject:
def __init__(self, attrs: dict):
self.attrs = attrs
class SpecialEncoder(json.JSONEncoder):
def default(self, o):
JE = json.JSONEncoder
if isinstance(o, SpecialObject):
return f"{{ ', '.join([f'{JE.encode(self, el[0])}: {JE.encode(el[1])}' for el in o.attrs.items()]) }}"
else:
return super().default(o)
但看起来JSONEncoder 再次编码了default 的返回值,因此我为自定义类型生成的字符串被序列化为字符串,输出类似于:
{
...
"special_object": "{ \"f1\": \"v1\", ..., \"fn\": \"vn\" }"
}
这显然不是我的想法。我还尝试像这里的一些答案所建议的那样覆盖JSONEncoder.encode 方法,但是该方法永远不会从JSONEncoder 本身中被调用。
我确实找到了 several approaches 来解决看似相似的问题,但那里提出的解决方案看起来太怪异,而且对于像我这样的任务来说过于复杂。
有没有办法在不深入JSONEncoder 的肠子的情况下,只用一两打代码来实现我所需要的?它不需要是一个通用的解决方案,只需我可以快速修复并且可能仅适用于单个案例。
【问题讨论】:
-
您想要的输出不是 JSON。
-
@Goyo,怎么样?它介于文档的漂亮打印和紧凑打印示例之间
-
因为任何 JSON 解析器在解析它时都会失败。我不明白你对这些例子的看法。
-
@Goyo, are you sure?
-
@OlvinRoght 那么
v2周围没有引号只是一个忽略,我们只是在这里谈论换行符?
标签: python json python-3.x serialization json-serialization