如何使简单的JSON序列化类可序列化

7

我有一个定义如下的类

class A:
    def __init__(self):
        self.item1 = None
    def __repr__(self):
        return str(self.__dict__)

当我执行以下操作时:
>>> import simplejson
>>> myA = A()
>>> simplejson.dumps(myA)
TypeError: {'item1': None} is not JSON serializable

我找不到原因。

我需要在A中添加特定的方法,以便simplejson可以序列化我的类对象吗?

2个回答

10

使用simplejson无法序列化任意对象。你需要向dumpload传递一个defaultobject_hook。以下是一个示例:

class SerializerRegistry(object):
    def __init__(self):
        self._classes = {}
    def add(self, cls):
        self._classes[cls.__module__, cls.__name__] = cls
        return cls
    def object_hook(self, dct):
        module, cls_name = dct.pop('__type__', (None, None))
        if cls_name is not None:
            return self._classes[module, cls_name].from_dict(dct)
        else:
            return dct
    def default(self, obj):
        dct = obj.to_dict()
        dct['__type__'] = [type(obj).__module__,
                           type(obj).__name__]
        return dct

registry = SerializerRegistry()

@registry.add
class A(object):
    def __init__(self, item1):
        self.item1 = item1
    def __repr__(self):
        return str(self.__dict__)
    def to_dict(self):
        return dict(item1=self.item1)
    @classmethod
    def from_dict(cls, dct):
        return cls(**dct)

s = json.dumps(A(1), default=registry.default)
a = json.loads(s, object_hook=registry.object_hook)

这将导致以下结果:

>>> s
'{"item1": 1, "__type__": ["__main__", "A"]}'
>>> a
{'item1': 1}

但是,你真正需要的是一个名为default的函数,它能够从你想要序列化的对象中创建字典,以及一个名为object_hook的函数,当给定字典时返回一个正确类型的对象(如果仅仅有字典是不够的)。最佳方法是在可序列化类上有一些方法,它们可以从对象创建一个字典,并且可以将其构建回来,同时还应该有一个映射,用于识别字典属于哪个类。

你也可以向类中添加标识符,用作_classes的索引。这样,如果必须移动一个类,则不会出现问题。


这个答案是正确的,但我没有检查它,因为这个例子不是很简单。谢谢! - dnuske

3
根据json模块文档(simplejson在Python 2.6中被采用为json),您需要扩展json.JSONEncoder类,覆盖其默认方法,以将您的对象转换为可序列化的类型。它似乎没有寻找您的对象上的方法。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接