python 使用 jsonpickle 从文件中保存和加载对象

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2398078/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-04 00:33:46  来源:igfitidea点击:

saving and loading objects from file using jsonpickle

pythonjsonserializationjsonpickle

提问by

I have the following simple methods for writing a python object to a file using jsonpickle:

我有以下使用 jsonpickle 将 python 对象写入文件的简单方法:

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?

问题是,每当我使用这些时,它都会将我的对象作为字典(具有诸如:“py/object”:“my_module.MyClassName”之类的字段)加载回,而不是作为用于生成类型的实际 Python 对象json 字符串。我怎样才能让 jsonpickle 实际上将加载的字符串转换回对象?

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?

而不是像:[Foo()]。我怎样才能解决这个问题?

thanks.

谢谢。

回答by

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.

正确答案是我没有继承自object. 如果不继承自object,jsonpickle 似乎无法正确解码在构造函数中采用一个或多个参数的类。我绝不是专家,而是制作它Foo(object):而不是Foo:在类声明中修复它。

回答by jfs

Make sure that use_jsonpickle == Truein json_load_file(). It seems that you serialize using jsonpickleand load using json.

确保use_jsonpickle == Truejson_load_file(). 似乎您序列化 usingjsonpickle和 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'>

回答by nuzzolilo

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://github.com/jsonpickle/jsonpickle/issues/210