【问题标题】:How to make simplejson serializable class如何使simplejson可序列化类
【发布时间】:2011-01-27 21:13:26
【问题描述】:

我有一个这样定义的类

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 序列化我的类对象?

【问题讨论】:

    标签: python serialization simplejson


    【解决方案1】:

    您不能使用simplejson 序列化任意对象。您需要将defaultobject_hook 传递给dumpload。这是一个例子:

    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 的索引。这样,如果您必须移动班级,您就不会遇到问题。

    【讨论】:

    • 这个答案是正确的,但我没有检查它,因为例子不是很简单。谢谢!
    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 2017-03-08
      • 2013-04-29
      • 1970-01-01
      • 2011-01-16
      • 2011-04-15
      • 2015-12-21
      • 2011-01-21
      相关资源
      最近更新 更多