saving and loading objects from file using jsonpickle

橙三吉。 提交于 2020-06-09 09:34:48

问题


I have the following simple methods for writing a python object to a file using 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

the problem is that whenever I use these, it loads my objects back as dictionaries (that have fields like: "py/object": "my_module.MyClassName") but not as an actual Python object of the type that was used to generate the json string. How can I make it so jsonpickle actually converts the loaded string back to the object?

to illustrate this with an example, consider the following:

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

This yields:

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

Rather than something like: [Foo()]. How can I fix this?

thanks.


回答1:


The correct answer was that I was not inheriting from object. Without inheriting from object, jsonpickle cannot correctly decode classes that take one or more arguments in the constructor, it seems. I am by no means an expert but making it Foo(object): rather than Foo: in the class declaration fixed it.




回答2:


Make sure that use_jsonpickle == True in json_load_file(). It seems that you serialize using jsonpickle and load using 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

Make sure that object type is available

>>> 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'>



回答3:


As of this posting, there is a bug which causes encoding to be wrong if the serialized object is an inner class. Make sure the class is not located within another class. I've filed an issue with the maintainer. https://github.com/jsonpickle/jsonpickle/issues/210



来源:https://stackoverflow.com/questions/2398078/saving-and-loading-objects-from-file-using-jsonpickle

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!