Сохранение и загрузка объектов из файла с помощью jsonpickle

У меня есть следующие простые методы для записи объекта python в файл с помощью jsonpickle:

def json_serialize(obj, filename, use_jsonpickle=True):
    f = open(filename, 'w')
    if use_jsonpickle:
        import jsonpickle
        json_obj = jsonpickle.encode(obj)
        f.write(json_obj)
    else:
        simplejson.dump(obj, f) 
    f.close()

def json_load_file(filename, use_jsonpickle=True):
    f = open(filename)
    if use_jsonpickle:
        import jsonpickle
        json_str = f.read()
        obj = jsonpickle.decode(json_str)
    else:
        obj = simplejson.load(f)
    return obj

проблема в том, что всякий раз, когда я их использую, он загружает мои объекты обратно как словари (которые имеют такие поля, как: "py/object": "my_module.MyClassName" ), но не как фактический объект Python используемого типа для генерации строки json. Как я могу это сделать, jsonpickle фактически преобразует загруженную строку обратно в объект?

чтобы проиллюстрировать это примером, рассмотрим следующее:

class Foo:
    def __init__(self, hello):
    self.hello = hello

# make a Foo obj
obj = Foo("hello world")
obj_str = jsonpickle.encode(obj)
restored_obj = jsonpickle.decode(obj_str)
list_objects = [restored_obj]
# We now get a list with a dictionary, rather than
# a list containing a Foo object
print "list_objects: ", list_objects

Это дает:

list_objects:  [{'py/object': 'as_events.Foo', 'hello': 'hello world'}]

Вместо чего-то вроде: [Foo()]. Как я могу это исправить?

спасибо.

Ответ 1

Правильный ответ заключался в том, что я не наследовал от object. Не наследуя от object, jsonpickle не может правильно декодировать классы, которые принимают один или несколько аргументов в конструкторе. Я отнюдь не эксперт, но вместо Foo(object): вместо Foo: в объявлении класса исправлено его.

Ответ 2

Убедитесь, что use_jsonpickle == True в json_load_file(). Кажется, что вы сериализуете использование jsonpickle и загружаете с помощью json.

>>> import jsonpickle
>>> class A(object):
...    def __init__(self, name):
...       self.name = name
... 
>>> js = jsonpickle.encode(A('abc'))
>>> js
'{"py/object": "__main__.A", "name": "abc"}'     # <-- json string
>>> a = jsonpickle.decode(js)
>>> a
<__main__.A object at 0x7f826a87bd90>            # <-- python object
>>> a.name
u'abc'
>>> import json
>>> b = json.loads(js)
>>> b
{u'py/object': u'__main__.A', u'name': u'abc'}    # <-- dictionary

Убедитесь, что тип объекта доступен

>>> del A
>>> c = jsonpickle.decode(js)                  # no type available
>>> c
{u'py/object': u'__main__.A', u'name': u'abc'}
>>> type(c)
<type 'dict'>
>>> class A(object):
...    def __init__(self, name):
...        self.name = name
... 
>>> d = jsonpickle.decode(js)                   # type is available
>>> d
<__main__.A object at 0x7f826a87bdd0>
>>> type(d)
<class '__main__.A'>