使用 jsonpickle 从文件中保存和加载对象
Posted
技术标签:
【中文标题】使用 jsonpickle 从文件中保存和加载对象【英文标题】:saving and loading objects from file using 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()
上下文管理器进行文件写入。当你在这里序列化时遇到错误,你会让你的文件保持打开状态——这很糟糕。
【参考方案1】:
截至本文发布时,如果序列化对象是内部类,则存在一个导致编码错误的错误。确保该类不在另一个类中。我已经向维护者提出了问题。 https://github.com/jsonpickle/jsonpickle/issues/210
【讨论】:
【参考方案2】:正确的答案是我没有从object
继承。如果没有从object
继承,jsonpickle 似乎无法正确解码在构造函数中采用一个或多个参数的类。我绝不是专家,但在类声明中使用Foo(object):
而不是Foo:
来修复它。
【讨论】:
【参考方案3】:确保use_jsonpickle == True
在json_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'>
【讨论】:
谁能告诉我 u'py/object': u'main.A', u'name': u'abc 中的这个“u”是什么' ? @ed22 它是how unicode string literals are written in Python 2。repr(unicode_string)
使用相同的文本表示。
非常感谢!以上是关于使用 jsonpickle 从文件中保存和加载对象的主要内容,如果未能解决你的问题,请参考以下文章
python3教程:jsonpickle和sqlite3持久化存储字典对象
python3教程:jsonpickle和sqlite3持久化存储字典对象
Python—序列化和反序列化模块(jsonpickle和shelve)