No puede serializar objetos arbitrarios con simplejson
. Debe pasar un default
y object_hook
a dump
y load
. He aquí un ejemplo:
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)
Esto se traduce en lo siguiente:
>>> s
'{"item1": 1, "__type__": ["__main__", "A"]}'
>>> a
{'item1': 1}
Pero lo que realmente necesita es una función default
que crea el diccionario de los objetos que desea serializar, y una función object_hook
que devuelve un objeto (del tipo correcto) cuando se le da un diccionario si un diccionario no es suficiente. El mejor enfoque es tener métodos en las clases serializables que crean un dict del objeto y que lo reconstruyen, y también para tener un mapeo que reconoce a qué clase pertenecen los diccionarios.
También puede agregar un identificador a las clases que se utilizarán como índice para _classes
. De esta forma no tendrías problemas si tienes que mover una clase.
esta respuesta es correcta, pero no la compruebo porque el ejemplo no es muy simple. ¡Gracias! – dnuske