为了账号安全,请及时绑定邮箱和手机立即绑定

将utf-8文本保存在json.dump中,作为UTF 8,而不是作为转义序列

将utf-8文本保存在json.dump中,作为UTF 8,而不是作为转义序列

湖上湖 2019-06-17 15:15:28
将utf-8文本保存在json.dump中,作为UTF 8,而不是作为转义序列样本代码:>>> import json>>> json_string = json.dumps("ברי צקלה")>>> print json_string"\u05d1\u05e8\u05d9 \u05e6\u05e7\u05dc\u05d4"问题是:它不是人类所能读的。我的(智能)用户希望验证甚至编辑带有JSON转储的文本文件。(我宁愿不使用XML)是否有方法将对象序列化为utf-8json字符串(而不是\uXXXX)?这没什么用:>>> output = json_string.decode('string-escape')"\u05d1\u05e8\u05d9 \u05e6\u05e7\u05dc\u05d4"这,这个很管用,但是如果有任何子对象是python-Unicode而不是utf-8,那么它将转储垃圾:>>> #### ok:>>> s= json.dumps( "ברי צקלה", ensure_ascii=False)    >>> print json.loads(s)   ברי צקלה>>> #### NOT ok: >>> d={ 1: "ברי צקלה", 2: u"ברי צקלה" }>>> print d{1: '\xd7\x91\xd7\xa8\xd7\x99 \xd7\xa6\xd7\xa7\xd7\x9c\xd7\x94',   2: u'\xd7\x91\xd7\xa8\xd7\x99 \xd7\xa6\xd7\xa7\xd7\x9c\xd7\x94'}>>> s = json.dumps( d, ensure_ascii=False, encoding='utf8')  >>> print json.loads(s)['1']ברי צקלה>>> print json.loads(s)['2']×רנצק××
查看完整描述

3 回答

?
慕少森

TA贡献2019条经验 获得超9个赞

使用ensure_ascii=False切换到json.dumps(),然后手动将值编码为UTF-8:

>>> json_string = json.dumps(u"ברי צקלה", ensure_ascii=False).encode('utf8')>>> json_string'"\xd7\x91\xd7\xa8\xd7\x99 \xd7\xa6\xd7\x
a7\xd7\x9c\xd7\x94"'>>> print json_string"ברי צקלה"

如果要将此写入文件,则可以使用io.open()而不是open()若要在编写时生成编码Unicode值的文件对象,请使用json.dump()相反,要写入该文件:

with io.open('filename', 'w', encoding='utf8') as json_file:
    json.dump(u"ברי צקלה", json_file, ensure_ascii=False)

在Python 3中,内置的open()的别名io.open()..请注意,有一个中的bugjson模块在那里ensure_ascii=False标志可以产生一个混和unicodestr物品。Python 2的解决方法是:

with io.open('filename', 'w', encoding='utf8') as json_file:
    data = json.dumps(u"ברי צקלה", ensure_ascii=False)
    # unicode(data) auto-decodes data to unicode if str
    json_file.write(unicode(data))

如果要传入字节字符串(键入str在Python 2中,bytes在Python 3中)编码为UTF-8,请确保同时设置encoding关键词:

>>> d={ 1: "ברי צקלה", 2: u"ברי צקלה" }>>> d{1: '\xd7\x91\xd7\xa8\xd7\x99 \xd7\xa6\xd7\xa7\xd7\x9c\xd7\x94', 2: u'\u05d1\u05e8\u05
d9 \u05e6\u05e7\u05dc\u05d4'}>>> s=json.dumps(d, ensure_ascii=False, encoding='utf8')>>> s
u'{"1": "\u05d1\u05e8\u05d9 \u05e6\u05e7\u05dc\u05d4", "2": "\u05d1\u05e8\u05d9 \u05e6\u05e7\u05dc\u05d4"}'>>> json.loads(s)['1']u'\u05d1\
u05e8\u05d9 \u05e6\u05e7\u05dc\u05d4'>>> json.loads(s)['2']u'\u05d1\u05e8\u05d9 \u05e6\u05e7\u05dc\u05d4'>>> print json.loads(s)['1']ברי
 צקלה>>> print json.loads(s)['2']ברי צקלה

请注意你的第二个样本是有效的Unicode;您将Utf-8字节作为Unicode文字,这将绝不可能工作:

>>> s = u'\xd7\x91\xd7\xa8\xd7\x99 \xd7\xa6\xd7\xa7\xd7\x9c\xd7\x94'>>> print s×רנצק××>>> print s.encode('latin1').decod
e('utf8')ברי צקלה

只有当我将该字符串编码为拉丁语1(其Unicode编码点将一对一映射为字节),然后解码为UTF-8时,您才会看到预期的输出。这与JSON无关,与使用错误输入有关。结果称为莫吉贝克.

如果从字符串文本中获得Unicode值,则使用错误的编解码器对其进行解码。可能是您的终端配置错误,或者您的文本编辑器使用与您让Python读取文件不同的编解码器保存了源代码。或者你从一个应用错误的编解码器库中获得了它。这些都与JSON库无关.


查看完整回答
1 反对 回复 2019-06-17
?
慕桂英3389331

TA贡献2036条经验 获得超8个赞

写入文件

import codecsimport jsonwith codecs.open('your_file.txt', 'w', encoding='utf-8') as f:
    json.dump({"message":"xin chào việt nam"}, f, ensure_ascii=False)

打印到stdin

import codecsimport jsonprint(json.dumps({"message":"xin chào việt nam"}, ensure_ascii=False))


查看完整回答
1 反对 回复 2019-06-17
?
万千封印

TA贡献1891条经验 获得超3个赞

更新:这是错误的答案,但理解错误的原因仍然是有用的。见评论。

怎么样unicode-escape?

>>> d = {1: "ברי צקלה", 2: u"ברי צקלה"}>>> json_str = json.dumps(d).decode('unicode-escape').encode('utf8')
>>> print json_str{"1": "ברי צקלה", "2": "ברי צקלה"}


查看完整回答
反对 回复 2019-06-17
  • 3 回答
  • 0 关注
  • 3363 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信