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标志可以产生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))
    

    如果您传递的是编码为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

    下一篇: Python: Saving API result into json file?