问题
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