json.dumps中的8个文本为UTF8,而不是\ u转义序列
示例代码:
>>> import json
>>> json_string = json.dumps("ברי צקלה")
>>> print json_string
"u05d1u05e8u05d9 u05e6u05e7u05dcu05d4"
问题是:这不是人类可读的。 我的(聪明)用户想要使用JSON转储验证甚至编辑文本文件。 (我宁愿不使用XML)
有没有办法将对象序列化为utf-8 json字符串(而不是 uXXXX)?
这没有帮助:
>>> output = json_string.decode('string-escape')
"u05d1u05e8u05d9 u05e6u05e7u05dcu05d4"
这是有效的,但如果任何子对象是一个python-unicode而不是utf-8,它会转储垃圾:
>>> #### ok:
>>> s= json.dumps( "ברי צקלה", ensure_ascii=False)
>>> print json.loads(s)
ברי צקלה
>>> #### NOT ok:
>>> d={ 1: "ברי צקלה", 2: u"ברי צקלה" }
>>> print d
{1: 'xd7x91xd7xa8xd7x99 xd7xa6xd7xa7xd7x9cxd7x94',
2: u'xd7x91xd7xa8xd7x99 xd7xa6xd7xa7xd7x9cxd7x94'}
>>> s = json.dumps( d, ensure_ascii=False, encoding='utf8')
>>> print json.loads(s)['1']
ברי צקלה
>>> print json.loads(s)['2']
××¨× ×¦×§××
我搜索了json.dumps文档,但找不到有用的东西。
编辑 - 解决方案(?):
我会尽量总结Martijn Pieters的评论和回答:
(编辑:@ Sebastian的评论和大约一年之后的第二个想法)
有可能是没有在 json.dumps内置的解决方案。
在它被JSON编辑之前,我必须将所有字符串转换为UTF8 Unicode对象。 我将使用马克的函数,可以在嵌套对象中方便地转换字符串
我给出的例子在很大程度上取决于我的计算机和IDE环境,并且在所有计算机上运行的都不一样。
谢谢大家 :)
使用ensure_ascii=False
开关到json.dumps()
,然后手动将值编码为UTF-8:
>>> json_string = json.dumps(u"ברי צקלה", ensure_ascii=False).encode('utf8')
>>> json_string
'"xd7x91xd7xa8xd7x99 xd7xa6xd7xa7xd7x9cxd7x94"'
>>> 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()
的别名。 请注意, json
模块中存在一个bug,其中ensure_ascii=False
标志可以产生unicode
和str
对象的混合。 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))
如果您传递的是编码为UTF-8的字节字符串(在Python 2中键入str
,Python 3中的bytes
),请确保也设置encoding
关键字:
>>> d={ 1: "ברי צקלה", 2: u"ברי צקלה" }
>>> d
{1: 'xd7x91xd7xa8xd7x99 xd7xa6xd7xa7xd7x9cxd7x94', 2: u'u05d1u05e8u05d9 u05e6u05e7u05dcu05d4'}
>>> s=json.dumps(d, ensure_ascii=False, encoding='utf8')
>>> s
u'{"1": "u05d1u05e8u05d9 u05e6u05e7u05dcu05d4", "2": "u05d1u05e8u05d9 u05e6u05e7u05dcu05d4"}'
>>> json.loads(s)['1']
u'u05d1u05e8u05d9 u05e6u05e7u05dcu05d4'
>>> json.loads(s)['2']
u'u05d1u05e8u05d9 u05e6u05e7u05dcu05d4'
>>> print json.loads(s)['1']
ברי צקלה
>>> print json.loads(s)['2']
ברי צקלה
需要注意的是你的第二个样本是不是有效的Unicode; 你给它UTF-8字节作为一个Unicode字面,这将永远不会工作:
>>> s = u'xd7x91xd7xa8xd7x99 xd7xa6xd7xa7xd7x9cxd7x94'
>>> print s
××¨× ×¦×§××
>>> print s.encode('latin1').decode('utf8')
ברי צקלה
只有当我将该字符串编码为拉丁语1(其unicode codepoints一对一映射到字节)时,才能以UTF-8解码,您是否看到预期的输出。 这与JSON无关,并且与使用错误输入有关。 结果被称为Mojibake。
如果您从字符串文本中获得该Unicode值,则会使用错误的编解码器对其进行解码。 它可能是你的终端配置错误,或者你的文本编辑器使用不同于你告诉Python读取文件的编解码器来保存你的源代码。 或者您从应用错误编解码器的库中获取它。 这一切都与JSON库无关 。
像蛋糕一样容易
写入文件
import codecs
import json
with 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 codecs
import json
print(json.dumps({"message":"xin chào việt nam"}, ensure_ascii=False))
更新:这是错误的答案,但它仍然有助于理解为什么它是错误的。 看评论。
如何unicode-escape
?
>>> d = {1: "ברי צקלה", 2: u"ברי צקלה"}
>>> json_str = json.dumps(d).decode('unicode-escape').encode('utf8')
>>> print json_str
{"1": "ברי צקלה", "2": "ברי צקלה"}
链接地址: http://www.djcxy.com/p/48691.html
上一篇: 8 texts in json.dumps as UTF8, not as \u escape sequence