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

发布于 2024-08-24 23:00:35 字数 1283 浏览 13 评论 0原文

我有以下简单的方法使用 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

问题是每当我使用这些方法时,它都会将我的对象作为字典加载回来(具有以下字段:“py/object”:“my_module.MyClassName” ),但不是用于生成 json 字符串的类型的实际 Python 对象。我怎样才能让 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()]。我该如何解决这个问题?

谢谢。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

叹倦 2024-08-31 23:00:35

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

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.

御守 2024-08-31 23:00:35

确保 json_load_file() 中的 use_jsonpickle == True。看来您使用 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'>

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'>
很糊涂小朋友 2024-08-31 23:00:35

截至本文发布时,存在一个错误,如果序列化对象是内部类,则会导致编码错误。确保该类不位于另一个类中。我已向维护者提出问题。 https://github.com/jsonpickle/jsonpickle/issues/210

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文