对于json.dumps的几个简单测试,来看看他的结果。
这里面有个选项ensure_ascii,默认是True,他会影响dumps输出的内容,如果为True:将自动将字符内容在输出时以\u
开头的字符串,即unicode-escape
模式,可以通过如下方式将他转成Unicode;此方式即使字典中有混合Unicode和str,在输出时都不会出问题。
"\u8fd9\u662f\u4e2autf8\u7f16\u7801\u7684\u5b57\u7b26\u4e32".decode("unicode-escape")
如果ensure_ascii=False,将在dumps过程中直接进行字符串对象的拼接(join),如果有混合Unicode和str存在将会出现异常,也就是str跟系统默认的字符编码不一致时,就会出现异常。
Python 2的json\encoder.py实现中有一段,如果默认的是encoding=utf-8模式是,文件中的字符串也是utf-8模式时,str不会decode为Unicode(处理过程中会存在Unicode和str同时存在的问题),在进行拼接(join)时跟系统默认编码不一致就会出现错误;而指定了encoding并且不是utf-8时,会将输入的字符串decode成Unicode,拼接(join)过程中都是Unicode,所以输出是就不会出现问题。
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)
处理UTF-8内容
不使用ensure_ascii
# -*- encoding: utf-8 -*- import json kv = { "str": "这是个utf8编码的字符串", } print json.dumps(kv)
{"str": "\u8fd9\u662f\u4e2autf8\u7f16\u7801\u7684\u5b57\u7b26\u4e32"}
使ensure_ascii=False
# -*- encoding: utf-8 -*- import json kv = { "str": "这是个utf8编码的字符串", } print json.dumps(kv, ensure_ascii=False)
{"str": "这是个utf8编码的字符串"}
处理UNICODE内容
不使用ensure_ascii
# -*- encoding: utf-8 -*- import json kv = { "unicode": u"这将是个Unicode形式保存的内容" } print json.dumps(kv)
{"unicode": "\u8fd9\u5c06\u662f\u4e2aUnicode\u5f62\u5f0f\u4fdd\u5b58\u7684\u5185\u5bb9"}
使ensure_ascii=False
# -*- encoding: utf-8 -*- import json kv = { "unicode": u"这将是个Unicode形式保存的内容" } print json.dumps(kv, ensure_ascii=False)
{"unicode": "这将是个Unicode形式保存的内容"}
混合UTF-8与UNICODE处理
不使用ensure_ascii
# -*- encoding: utf-8 -*- import json kv = { "str": "这是个utf8编码的字符串", "unicode": u"这将是个Unicode形式保存的内容" } print json.dumps(kv)
{"unicode": "\u8fd9\u5c06\u662f\u4e2aUnicode\u5f62\u5f0f\u4fdd\u5b58\u7684\u5185\u5bb9", "str": "\u8fd9\u662f\u4e2autf8\u7f16\u7801\u7684\u5b57\u7b26\u4e32"}
使ensure_ascii=False
# -*- encoding: utf-8 -*- import json kv = { "str": "这是个utf8编码的字符串", "unicode": u"这将是个Unicode形式保存的内容" } print json.dumps(kv, ensure_ascii=False)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe8 in position 1: ordinal not in range(128)