我有一个复杂的JSON可序列化数据结构,其中包含unicode字符串和utf-8字节字符串。
当我尝试使用ensure_ascii=False
序列化结构时,它失败了:
Python 2.7.5+ (default, Sep 19 2013, 13:48:49)
[GCC 4.8.1] on linux2
>>> import json
>>> json.dumps(['\xd0\xb2', u'\xd0\xb2'], ensure_ascii=False)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python2.7/json/__init__.py", line 250, in dumps
sort_keys=sort_keys, **kw).encode(obj)
File "/usr/lib/python2.7/json/encoder.py", line 210, in encode
return ''.join(chunks)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xd0 in position 1: ordinal not in range(128)
>>>
我理解为什么this happens,但是有一种更简单或内置的方式使它工作而不是递归迭代数据结构,找到字节串并将它们解码为unicode吗?
答案 0 :(得分:3)
AFAIK序列化为JSON格式的原因是存储或传输一些信息。如果您指定ensure_ascii = False
,则非ascii字符不会被编码,这根本没有意义,因为您希望对数据进行编码和序列化。
基本上你试图获得一个非编码字符的字符串,这是不可能的。
来自官方文档:
如果ensure_ascii为True(默认值),则输出中的所有非ASCII字符都使用\ uXXXX序列进行转义,结果是仅包含ASCII字符的str实例。如果ensure_ascii为False,则写入fp的一些块可能是unicode实例。这通常是因为输入包含unicode字符串或使用编码参数。除非fp.write()明确理解unicode(如在codecs.getwriter()中),否则这可能会导致错误。
另一方面,您正在设计API的事实并不表示您无法控制输入。 API在某种程度上是一个契约:如果给出了一些输入,则返回一些输出。因此,您可以而且应该始终指定您的期望。
在您的情况下,您可以逐个检查元素,并将bytestring转换为unicode。话虽如此,我的建议是强制您的用户使用unicode 和不要指定 ensure_ascii = False
对我来说,理解编码和避免问题的一般规则是: