8

这对我来说似乎不可能使用标准库json模块。使用json.dumps时它会自动转义所有非 ASCII 字符,然后将字符串编码为 ASCII。我可以指定它不转义非 ASCII 字符,但是当它尝试将输出转换为 ASCII 时它会崩溃。

问题是 -我不想要 ASCII!我只想将我的 JSON 字符串作为unicode(或UTF-8)字符串返回。有没有方便的方法来做到这一点?

这是一个演示我想要的示例:

d = {'navn': 'Åge', 'stilling': 'Lærling'}
json.dumps(d, output_encoding='utf8')
# => '{"stilling": "Lærling", "navn": "Åge"}'

但是当然,没有像output_encoding这样的选项,所以这是实际的输出:

d = {'navn': 'Åge', 'stilling': 'Lærling'}
json.dumps(d)
# => '{"stilling": "L\\u00e6rling", "navn": "\\u00c5ge"}'

总而言之 - 我想将 Python dict 转换为UTF-8 JSON 字符串而没有任何转义。我怎样才能做到这一点?


我会接受以下解决方案:

  • Hacks(预处理和后处理输入以dumps达到预期效果)
  • 子类化JSONEncoder(我不知道它是如何工作的,文档也不是很有帮助)
  • PyPi 上可用的第三方库
4

3 回答 3

7

要求

  • 确保您的 python 文件以 UTF-8 编码。否则你的非 ASCII 字符会变成问号,?. Notepad++ 为此提供了出色的编码选项。

  • 确保包含适当的字体。如果要显示日文字符,则需要安装日文字体。

  • 确保您的 IDE 支持显示 Unicode 字符。否则你可能会UnicodeEncodeError抛出一个错误。

例子:

UnicodeEncodeError: 'charmap' codec can't encode characters in position 22-23: character maps to <undefined>

PyScripter 为我工作。它包含在http://portablepython.com/wiki/PortablePython3.2.1.1的“便携式 Python”中

  • 确保你使用的是 Python 3+,因为这个版本提供了更好的 unicode 支持。

问题

json.dumps() 转义 unicode 字符。

解决方案

阅读底部的更新。或者...

用解析的 unicode 字符替换每个转义字符。

我创建了一个简单的 lambda 函数getStringWithDecodedUnicode,它就是这样做的。

import re   
getStringWithDecodedUnicode = lambda str : re.sub( '\\\\u([\da-f]{4})', (lambda x : chr( int( x.group(1), 16 ) )), str )

getStringWithDecodedUnicode是一个常规功能。

def getStringWithDecodedUnicode( value ):
    findUnicodeRE = re.compile( '\\\\u([\da-f]{4})' )
    def getParsedUnicode(x):
        return chr( int( x.group(1), 16 ) )

    return  findUnicodeRE.sub(getParsedUnicode, str( value ) )

例子

testJSONWithUnicode.py(使用 PyScripter 作为 IDE)

import re
import json
getStringWithDecodedUnicode = lambda str : re.sub( '\\\\u([\da-f]{4})', (lambda x : chr( int( x.group(1), 16 ) )), str )

data = {"Japan":"日本"}
jsonString = json.dumps( data )
print( "json.dumps({0}) = {1}".format( data, jsonString ) )
jsonString = getStringWithDecodedUnicode( jsonString )
print( "Decoded Unicode: %s" % jsonString )

输出

json.dumps({'Japan': '日本'}) = {"Japan": "\u65e5\u672c"}
Decoded Unicode: {"Japan": "日本"}

更新

或者...只是ensure_ascii=False作为 json.dumps 的选项传递。

注意:您需要满足我在开头概述的要求,否则这将不起作用。

import json
data = {'navn': 'Åge', 'stilling': 'Lærling'}
result = json.dumps(d, ensure_ascii=False)
print( result ) # prints '{"stilling": "Lærling", "navn": "Åge"}'
于 2012-07-28T08:48:19.340 回答
6

encode_ascii=False恕我直言,这是最好的解决方案。

如果您使用的是 Python2.7,这里是示例 python 文件:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# example.py
from __future__ import unicode_literals
from json import dumps as json_dumps
d = {'navn': 'Åge', 'stilling': 'Lærling'}
print json_dumps(d, ensure_ascii=False).encode('utf-8')
于 2014-03-07T10:13:06.610 回答
0

如果在 Python3.7 上,这对我有用

from __future__ import unicode_literals
print json.dumps(m,ensure_ascii=False)

确保from __future__ import unicode_literals是要导入的第一行。

于 2021-08-03T16:05:05.873 回答