python - 如何对自定义迭代进行 json 序列化?
问题描述
我想创建一种行为类似于命名元组的类型,除了它具有自定义表示形式,当序列化为 JSON 时也会受到尊重。
天真的书本方法是这样的:
from typing import NamedTuple
import json
class MyPair(NamedTuple):
left: str
right: str
def __repr__(self):
return self.left + ':' + self.right
class MyJSONEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, MyPair):
return str(obj)
return json.JSONEncoder.default(self, obj)
现在print(MyPair('a', 'b'))
将按预期输出a:b
,但print(json.dumps([MyPair('a', 'b')], cls=MyJSONEncoder))
将产生[["a", "b"]]
因为default()
仅当对象不能原始序列化为 JSON 时才调用。由于我自己的类型是一个元组,它会在我有机会干预之前被序列化。
在用字符串替换所有对象的预处理步骤中,是否有任何好的或不太好的方法来实现这一点,而MyPair
不是不做Tuple
或迭代整个文档?MyPair
编辑:为了解决 Joran 的回答,我仍然希望保留序列化仅包含偶尔MyPair
s 的复杂树的能力。抱歉,我的最小示例可能没有说清楚。
解决方案
只包含默认参数
def my_class_encoder(o):
if isinstance(o,MyClass):
return repr(o)
json.dumps(myClassInstance,default=my_class_encoder)
它比真正的编码器更容易处理
……
但实际上只是在您的课程中添加一个 def
class MyPair(NamedTuple):
left: str
right: str
def serialize(self):
return list(self)
def __repr__(self):
return self.left + ':' + self.right
然后就
json.dumps(myClassInstance.serialize())
这样做的好处是更清楚它在做什么(至少恕我直言)
推荐阅读
- typescript - 如何在 Vue3 SFC 中导入打字稿文件并使用 laravel mix 构建它
- flutter - 从本地设备 Flutter 加载视频
- python - Python在Django应用程序中抛出变量范围错误
- sql - 如何将表格 CSV 拆分为行
- cmd - 错误 AttributeError:模块 'twint' 没有属性 'config'
- python - Python Google Classroom API“TypeError:列表索引必须是整数或切片,而不是 str”
- javascript - gsap 说 e 没有定义
- javascript - 如何使用 Cypress 配置 Cookie?
- php - Laravel 从 URL 更改主键会导致错误
- dataframe - Julia - 搜索所有列缺失的行并删除这些行的函数