如何制作simplejson可序列化类

dnu*_*ske 7 python serialization simplejson

我有一个像这样定义的类

class A:
    def __init__(self):
        self.item1 = None
    def __repr__(self):
        return str(self.__dict__)
Run Code Online (Sandbox Code Playgroud)

当我做:

>>> import simplejson
>>> myA = A()
>>> simplejson.dumps(myA)
TypeError: {'item1': None} is not JSON serializable
Run Code Online (Sandbox Code Playgroud)

我找不到原因.

我是否需要向A添加任何特定方法以使simplejson序列化我的类对象?

Ros*_*ron 10

您无法使用序列化任意对象simplejson.你需要传递defaultobject_hookdumpload.这是一个例子:

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)
Run Code Online (Sandbox Code Playgroud)

这导致:

>>> s
'{"item1": 1, "__type__": ["__main__", "A"]}'
>>> a
{'item1': 1}
Run Code Online (Sandbox Code Playgroud)

但是你真正需要的是一个default从你希望序列化的对象创建字典的函数,以及一个object_hook在字典不够时给它一个字典的函数,它返回一个对象(正确类型).最好的方法是在可序列化类上创建方法,这些类从对象创建一个dict并将其构造回来,并且还有一个映射可以识别字典所属的类.

您还可以向要用作索引的类添加标识符_classes.这样,如果必须移动一个类,就不会有问题.