【Python序列化】TypeError: Object of type xxx is not JSON serializable问题的解决方案
【Python序列化】TypeError: Object of type xxx is not JSON serializable问题的解决方案
尤其是type 为自定义类时。
问题现象
报错如下
TypeError: Object of type xxx is not JSON serializable
根因分析
对于自定义的对象,我们也可以通过继承JSONEncoder类实现它的序列化;但该方法转换后为字符串无法再次dumps,只是这个方法比较通用不用每个类单独写2dict方法。
import json#定义一个UserOnline类
class UserOnline(object):def __init__(self, userName, ipaddr, tokenId, deptName, loginLocation, browser, os, loginTime):self.userName = userNameself.ipaddr = ipaddrself.tokenId = tokenIdself.deptName = deptNameself.loginLocation = loginLocationself.browser = browserself.os = osself.loginTime = loginTime#定义一个转换函数,将UserOnline类换成json可以接受的类型;但该方法转换后为字符串无法再次dumps
def UserOnline2dict(std):return {'dm': std.userName,'ipaddr': std.ipaddr,'tokenId': std.tokenId,'deptName': std.deptName,'loginLocation': std.loginLocation,'browser': std.browser,'os': std.os,'loginTime': std.loginTime}# 对于自定义的对象,我们也可以通过继承JSONEncoder类实现它的序列化;但该方法转换后为字符串无法再次dumps,只是这个方法比较通用不用每个类单独写2dict方法
# 该方法转换后为字符串无法再次dumps,解决方案就是再次dumps序列化之前先loads一次还原为dict类型
class MyJSONEncoder(json.JSONEncoder):def default(self, obj):d = {}# d['__class__'] = obj.__class__.__name__# d['__module__'] = obj.__module__d.update(obj.__dict__)return d
究其根因该方法转换后为字符串再次dumps里面又嵌套了一层字符串,解析时就无法解析里面嵌套的那一层
解决方案
所以解决方案就是再次dumps序列化之前先loads一次还原为dict类型。
数据生成代码如下:
datas.append(cUserOnline)# return datas# datas = json.dumps(datas, default=UserOnline2dict)return json.dumps(datas, cls=MyJSONEncoder)
HTTP响应打包数据处理代码如下:
# 因为reData已经被dumps序列化一次了,如果再次dumps序列化后读出来每个元素都是字符串而不是dict;故此再次dumps序列化之前先loads(reData),这样就满足需求了。load_Data = json.loads(reData)dump_Data = json.dumps({'code': 200, 'msg': msg, 'rows': load_Data, 'total': len(reData)})return dump_Data