You cannot serialize arbitrary objects using simplejson . You need to pass default and object_hook to dump and load . Here is an example:
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)
The result is the following:
>>> s '{"item1": 1, "__type__": ["__main__", "A"]}' >>> a {'item1': 1}
But you really need the default function, which creates a dictionary from the objects you want to serialize, and the object_hook function, which returns an object (of the correct type) when a dictionary is provided, if the dictionary is not enough. The best approach is to have methods of serializable classes that create a dict from the object and that will return it, and also have a mapping that recognizes which class the dictionaries belong to.
You can also add an identifier to the classes that will be used as the index for _classes . This way you will have no problem if you need to move the class.
Rosh oxymoron
source share