简体   繁体   English

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

[英]saving and loading objects from file using jsonpickle

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. 问题是,无论何时我使用它们,它都会将我的对象作为字典(具有类似“py / object”:“my_module.MyClassName”)的字段加载回来,而不是用作生成的类型的实际Python对象json字符串。 How can I make it so jsonpickle actually converts the loaded string back to the object? 我怎么能这样做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()]. 而不是像:[Foo()]。 How can I fix this? 我怎样才能解决这个问题?

thanks. 谢谢。

The correct answer was that I was not inheriting from object . 正确的答案是我没有从object继承。 Without inheriting from object , jsonpickle cannot correctly decode classes that take one or more arguments in the constructor, it seems. 在没有继承自object ,jsonpickle无法正确解码构造函数中带有一个或多个参数的类。 I am by no means an expert but making it Foo(object): rather than Foo: in the class declaration fixed it. 我绝不是专家但是把它变成Foo(object):而不是Foo:在类声明中修复它。

Make sure that use_jsonpickle == True in json_load_file() . 确保json_load_file()中的use_jsonpickle == True It seems that you serialize using jsonpickle and load using json . 看来你使用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

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM