编写以下两个函数,用于存储和检索任何使用json和jsonpickle(在2.7中)的组合的Python(内置或用户定义)对象
def save(kind, obj):
pickled = jsonpickle.encode(obj)
filename = DATA_DESTINATION[kind] \\returns file destination to store json
if os.path.isfile(filename):
open(filename, 'w').close()
with open(filename, 'w') as f:
json.dump(pickled, f)
def retrieve(kind):
filename = DATA_DESTINATION[kind] \\returns file destination to store json
if os.path.isfile(filename):
with open(filename, 'r') as f:
pickled = json.load(f)
unpickled = jsonpickle.decode(pickled)
print unpickled
我没有用用户定义的对象测试这两个函数,但是当我尝试保存()内置的字符串字典时,(即{'Adam':'Age 19','Bill', '年龄32'}),我检索相同的文件,我在unicode中获得相同的字典,{u'Adam':u'Age 19',u'Bill',u'Age 32'}。我认为json / jsonpickle默认编码为utf-8,这里的交易是什么?
[更新]:删除所有jsonpickle编码/解码不会影响输出,仍然在unicode,似乎与json的问题?也许我做错了什么。
答案 0 :(得分:3)
import jsonpickle
import json
jsonpickle.set_preferred_backend('json')
jsonpickle.set_encoder_options('json', ensure_ascii=False);
print( jsonpickle.encode( { "value" : "значение"}) )
{“value”:“значение”}
答案 1 :(得分:1)
您可以在调用loads()后对unicode sting进行编码。
json.loads('"\\u79c1"').encode('utf-8')
现在你又有了一个普通的字符串。
答案 2 :(得分:0)
我认为json ...默认编码为utf-8,这里的交易是什么?
不,它编码为ASCII。它解码为unicode
。
>>> json.dumps(u'私')
'"\\u79c1"'
>>> json.loads('"\\u79c1"')
u'\u79c1'
答案 3 :(得分:0)
问题在于json作为一种序列化格式,其表达力不足以传递有关原始字符串类型的信息。换句话说,如果你有一个json字符串a
,你无法判断它是来自python字符串"a"
还是来自python unicode 字符串{{1 }}
事实上,您可以在documentation of the json module中阅读有关选项u"a"
的信息。基本上,根据你要编写生成的json的位置,你可以容忍一个unicode字符串,或者需要一个ascii字符串,所有传入的unicode字符都被正确转义。
例如:
ensure_ascii
正如您所看到的,根据>>> import json
>>> json.dumps({'a':'b'})
'{"a": "b"}'
>>> json.dumps({'a':u'b'}, ensure_ascii=False)
u'{"a": "b"}'
>>> json.dumps({'a':u'b'})
'{"a": "b"}'
>>> json.dumps({u'a':'b'})
'{"a": "b"}'
>>> json.dumps({'a':u'\xe0'})
'{"a": "\\u00e0"}'
>>> json.dumps({'a':u'\xe0'}, ensure_ascii=False)
u'{"a": "\xe0"}'
的值,您最终得到的是ascii json字符串或unicode字符串,但原始对象的组件都被平铺为相同的公共编码。特别关注ensure_ascii
案例。
{"a": "b"}
只是使用jsonpickle
作为其底层序列化引擎,不添加额外的元数据来跟踪原始字符串类型,因此您实际上是在丢失信息。
json