关于json.dumps的使用和解决Object of type XXX is not JSON serializable错误
使用python的json.dumps导出mongo数据时, 出现报错Object of type XXX is not JSON serializable
原因是自定义类以及mongo自动生成的ObjectId类型没有默认序列化操作, 需要继承json.JSONEncoder实现对应类型序列化
import copy
import json
from bson.objectid import ObjectId
from dataclasses import dataclass
# 自定义类
@dataclass
class A():
target_id: str = '123'
name: str = 'class A'
vol: int = 100
# 自定义序列化类
class MyEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, ObjectId): # 序列化类 ObjectId to Str
return str(obj)
elif isinstance(obj, A): # 序列化自定义类A to Dict
return {'target_id': obj.target_id,
'name': obj.name,
'vol': obj.vol}
else: # 其他类型使用默认序列化操作
return super(MyEncoder, self).default(obj)
a = A()
b = copy.deepcopy(a)
b.name = 'A b'
dict = {'_id': 1, 'data': [a]}
json_str = json.dumps(dict, indent=4, ensure_ascii=False, cls=MyEncoder)
print(json_str)
dict['data'].extend([b])
json_str = json.dumps(dict, indent=4, ensure_ascii=False, cls=MyEncoder)
print(json_str)
target_file = open('target.json', 'w+', encoding='utf-8')
target_file.write(json_str)
target_file.close()
运行结果target.json:
{
"_id": 1,
"data": [
{
"target_id": "123",
"name": "class A",
"vol": 100
},
{
"target_id": "123",
"name": "A b",
"vol": 100
}
]
}