将类实例序列化为 JSON

新手上路,请多包涵

我正在尝试创建一个类实例的 JSON 字符串表示并且遇到了困难。假设这个类是这样构建的:

 class testclass:
    value1 = "a"
    value2 = "b"

对 json.dumps 的调用是这样的:

 t = testclass()
json.dumps(t)

它失败并告诉我测试类不是 JSON 可序列化的。

 TypeError: <__main__.testclass object at 0x000000000227A400> is not JSON serializable

我也尝试过使用 pickle 模块:

 t = testclass()
print(pickle.dumps(t, pickle.HIGHEST_PROTOCOL))

它提供类实例信息,但不提供类实例的序列化内容。

 b'\x80\x03c__main__\ntestclass\nq\x00)\x81q\x01}q\x02b.'

我究竟做错了什么?

原文由 ferhan 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 900
2 个回答

基本问题是 JSON 编码器 json.dumps() 只知道如何序列化一组有限的对象类型,所有内置类型。在此处列出: https ://docs.python.org/3.3/library/json.html#encoders-and-decoders

一个好的解决方案是让您的类继承自 JSONEncoder 然后实现 JSONEncoder.default() 函数,并使该函数为您的类发出正确的 JSON。

一个简单的解决方案是在该实例的 .__dict__ 成员上调用 json.dumps() 。那是一个标准的 Python dict 如果你的类很简单,它将是 JSON 可序列化的。

 class Foo(object):
    def __init__(self):
        self.x = 1
        self.y = 2

foo = Foo()
s = json.dumps(foo) # raises TypeError with "is not JSON serializable"

s = json.dumps(foo.__dict__) # s set to: {"x":1, "y":2}

此博客文章中讨论了上述方法:

使用 _ dict _ 将任意 Python 对象序列化为 JSON

当然,Python 提供了一个内置函数,可以为您访问 .__dict__ ,称为 vars()

所以上面的例子也可以这样写:

 s = json.dumps(vars(foo)) # s set to: {"x":1, "y":2}

原文由 steveha 发布,翻译遵循 CC BY-SA 4.0 许可协议

有一种方法对我很有效,您可以尝试一下:

json.dumps() 可以采用可选参数 default ,您可以在其中为未知类型指定自定义序列化程序函数,在我的例子中看起来像

def serialize(obj):
    """JSON serializer for objects not serializable by default json code"""

    if isinstance(obj, date):
        serial = obj.isoformat()
        return serial

    if isinstance(obj, time):
        serial = obj.isoformat()
        return serial

    return obj.__dict__

前两个 ifs 用于日期和时间序列化,然后有一个 obj.__dict__ 为任何其他对象返回。

最后的电话看起来像:

 json.dumps(myObj, default=serialize)

当您正在序列化一个集合并且您不想为每个对象显式调用 __dict__ 时,它特别好。这是自动为您完成的。

到目前为止,对我来说效果很好,期待您的想法。

原文由 Broccoli 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题