当在Python中使用json.dumps()
或json.dump()
函数将对象或数据结构转化为JSON字符串时,有时会遇到报错xx is not JSON serializable
的问题,这是由于Python数据结构中,某些数据类型无法被直接序列化为JSON格式,例如 datetime.datetime、bytes、set等Python所独有的数据结构。本攻略将详细讲解如何解决这个问题。
原因
在Python的json库中,dumps()
和dump()
函数默认使用的编码器只能处理Python内置类型,比如dict, list, tuple, string, int, float等数据类型。如果在对象中出现Python内置类型以外的数据类型,则会报错。
解决办法
解决方案是使用json.dumps()和json.dump()函数的另一个可选参数default,该参数指定了在序列化对象中遇到不可序列化的对象时所使用的函数。下面是一些解决办法。
1.自定义default函数
自定义default函数,用来转化那些无法被json库直接编码的数据类型。示例代码如下:
import json
from datetime import datetime
class DateEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, datetime):
return obj.strftime('%Y-%m-%d %H:%M:%S')
else:
return json.JSONEncoder.default(self, obj)
if __name__ == '__main__':
data = {
'name': 'Tom',
'age': 20,
'time': datetime.now()
}
json_str = json.dumps(data, cls=DateEncoder)
print(json_str)
输出结果:
{"name": "Tom", "age": 20, "time": "2021-07-28 11:10:12"}
2.使用to_dict()函数
如果需要序列化的对象是自己编写的类,则可以在类中定义to_dict()函数,将类对象转化为dict。示例如下:
import json
class User:
def __init__(self, name, age):
self.name = name
self.age = age
def to_dict(self):
return {'name': self.name, 'age': self.age}
if __name__ == '__main__':
user = User("Tom", 21)
user_dict = user.to_dict()
json_str = json.dumps(user_dict)
print(json_str)
输出结果:
{"name": "Tom", "age": 21}
总结
以上两种解决办法可以帮助开发者轻松解决JSON序列化错误的问题。在上述过程中需要注意的是,在使用自定义default函数的时候,需要保证JSONEncoder调用的类方法比较统一。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Python json 错误xx is not JSON serializable解决办法 - Python技术站