【问题标题】:JSON serialize objects in Python in list / diconaryJSON在列表/字典中序列化Python中的对象
【发布时间】:2018-07-24 14:35:38
【问题描述】:

我对 Python 很陌生,我有一个相当大且复杂的数据结构,它是一个包含不同对象列表的字典列表。当我尝试通过 json.dumps() 将其转换为 JSON 时,我得到了标准

TypeError: <...> is not JSON serializable

我做了一些研究,大多数答案都指向编写自定义编码器的标准方法,这很好,我可以做到。但是,我希望能够将我的整个数据结构发送到 json.dumps() 而不是遍历所有内容,找出它是什么类,然后从头开始构建一个 json 对象。

有没有办法给python类本身添加编码器/解码器功能,所以当我向json.dumps发送复杂的数据结构时,类本身就知道该怎么做了。

是否有一些神奇的 to_json 或某种方法可以在 json.dumps 遇到该类时向该类添加自定义解码器?

【问题讨论】:

  • 你能分享你提供的json数据吗?

标签: python json


【解决方案1】:

当您使用 json.dumps(my_object, cls=MyCustomJsonEncoder) 时,自定义编码器类会为您处理。您的自定义编码器将覆盖default 方法,该方法采用self 和对象o 进行编码;测试需要自定义序列化的不同类型,然后使用super(MyCustomJsonEncoder, self).default(o) 将其余类型传递给默认值。

我经常使用的一个简单例子如下:

class JSONEncoder(json.JSONEncoder):
    """
    Enhancement of base JSONEncoder, also handling these objects:
     * datetime.datetime
     * decimal.Decimal
     * uuid.UUID
    """

    def default(self, o):
        if isinstance(o, Decimal):
            return float(o)
        elif isinstance(o, UUID):
            return str(o)
        elif isinstance(o, datetime):
            return {
                '__type__': 'datetime',
                '__value__': o.isoformat(),
            }
        return super(JSONEncoder, self).default(o)

    @staticmethod
    def dumps(obj):
        return json.dumps(obj, cls=JSONEncoder)

【讨论】:

  • 我得到一个 AttributeError: 'super' object has no attribute 'default' 我添加了一些日志记录并且它在类型上阻塞了: 'stringmap' 我该怎么做?
【解决方案2】:

正如 Steven Wolfe 在this thread 中所说,您可能需要查看jsonpickle。该库允许对复杂的 Python 对象进行编码和解码。

你可以这样使用它:

import jsonpickle

f = open(filename, 'w')
encoded_string = jsonpickle.encode(obj)
f.write(encoded_string)
f.close()

要将数据作为 Python 对象检索,只需使用 jsonpickle.decode(encoded_string) 方法。正如文档所说:

新对象具有相同的类型和数据,但现在基本上是原始对象的副本。

我认为这对你很有效。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-13
    • 1970-01-01
    • 2013-05-23
    • 2012-09-06
    相关资源
    最近更新 更多