【问题标题】:saving and loading objects from file using jsonpickle使用 jsonpickle 从文件中保存和加载对象
【发布时间】:2011-01-24 18:43:26
【问题描述】:

我有以下使用 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”),而不是作为所使用类型的实际 Python 对象生成 json 字符串。如何让 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()]。我该如何解决这个问题?

谢谢。

【问题讨论】:

  • 你能在jsonpickle.decode() 行之前import as_events 吗?
  • FWIW 这是一个很好的例子,说明何时应该使用with open() 上下文管理器进行文件写入。当你在这里序列化时遇到错误,你会让你的文件保持打开状态——这很糟糕。

标签: python json serialization jsonpickle


【解决方案1】:

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

      确保use_jsonpickle == Truejson_load_file() 中。您似乎使用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'>
      

      【讨论】:

      猜你喜欢
      • 2021-02-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-10
      • 2011-05-30
      • 2017-09-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多