为什么python json.dumps抱怨ascii解码?

2024-09-28 21:26:45 发布

您现在位置:Python中文网/ 问答频道 /正文

我的代码中有以下几行

outs = codecs.getwriter('utf-8')(sys.stdout)
# dJSON contains JSON message with non-ASCII chars
outs.write(json.dumps(dJSON,encoding='utf-8', ensure_ascii=False, indent=indent_val))

我得到以下异常:

    outs.write(json.dumps(dJSON,encoding='utf-8', ensure_ascii=False, indent=indent_val))
    File "/usr/lib/python2.7/json/__init__.py", line 238, in dumps
         **kw).encode(obj)
    File "/usr/lib/python2.7/json/encoder.py", line 204, in encode
         return ''.join(chunks)
    UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 27: ordinal not in range(128)

通过在json.dumps语句中指定encoding='utf-8',我避免了这类问题。为什么我还是会犯错?


Tags: injsonfalseusrasciivalutfencoding
3条回答

根据前面的回答,您可以使用utf8utf-8来解决这个问题,但它不包括“copy-paste-this”修复。

这是复制粘贴修复;p

your_unicode_result = json.dumps(your_dict, encoding="utf8", ensure_ascii=False)

有一个解决方法:传递utf8编码(而不是utf-8!)转储方法。在这种情况下,它将强制所有字符串首先解码为unicode,您可以使用unicode字符串和已经编码为UTF-8的字符串的混合。为什么有效?因为在JSONEncoder的源代码中有这样一个东西:

if self.encoding != 'utf-8':
     def _encoder(o, _orig_encoder=_encoder, _encoding=self.encoding):
         if isinstance(o, str):
             o = o.decode(_encoding)
         return _orig_encoder(o)

这是我们所需要的,这是不可能的。但是当我们将编码改为utf8(这与utf-8完全相同的UTF-8)时,我们强制定义这个_encoder,并且一切正常:)

我的猜测是dJSON对象不包含纯unicode,但它包含unicode和已编码为utf-8的字符串的混合,例如,这将失败

>>> d = {u'name':u'पाइथन'.encode('utf-8')}
>>> json.dumps(d, encoding='utf-8', ensure_ascii=False)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/__init__.py", line 238, in dumps
    **kw).encode(obj)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/encoder.py", line 204, in encode
    return ''.join(chunks)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe0 in position 1: ordinal not in range(128)

但这是可行的(所有的unicode)

>>> d = {u'name':u'पाइथन'}
>>> json.dumps(d, encoding='utf-8', ensure_ascii=False)
u'{"name": "\u092a\u093e\u0907\u0925\u0928"}

尽管这也有效(所有字符串)

>>> d = {'name':u'पाइथन'.encode('utf-8')}
>>> json.dumps(d, encoding='utf-8', ensure_ascii=False)
'{"name": "\xe0\xa4\xaa\xe0\xa4\xbe\xe0\xa4\x87\xe0\xa4\xa5\xe0\xa4\xa8"}'

相关问题 更多 >