Json.dump失败了'必须是unicode,而不是str'TypeError

Iro*_*Man 17 python unicode encoding json python-2.7

我有一个json文件恰好有大量的中文和日文(和其他语言)字符.我将它加载到我的python 2.7脚本中,使用io.open如下:

with io.open('multiIdName.json', encoding="utf-8") as json_data:
    cards = json.load(json_data)
Run Code Online (Sandbox Code Playgroud)

我向json添加了一个新属性,一切都很好.然后我尝试将其写回另一个文件:

with io.open("testJson.json",'w',encoding="utf-8") as outfile:
        json.dump(cards, outfile, ensure_ascii=False)
Run Code Online (Sandbox Code Playgroud)

那是我收到错误的时候 TypeError: must be unicode, not str

我尝试将outfile写为binary(with io.open("testJson.json",'wb') as outfile:),但我最终得到的东西:

{"multiverseid": 262906, "name": "\u00e6\u00b8\u00b8\u00e9\u009a\u00bc\u00e7\u008b\u00ae\u00e9\u00b9\u00ab", "language": "Chinese Simplified"}
Run Code Online (Sandbox Code Playgroud)

我认为用相同的编码打开和写它就足够了,还有ensure_ascii标志,但显然不是.我只想在运行脚本之前保留文件中存在的字符,而不将它们变成\ u.

Yar*_*ron 29

你能试试以下吗?

with io.open("testJson.json",'w',encoding="utf-8") as outfile:
  outfile.write(unicode(json.dumps(cards, ensure_ascii=False)))
Run Code Online (Sandbox Code Playgroud)


Ant*_*ala 5

该错误的原因是json.dumpsPython 2中完全愚蠢的行为:

>>> json.dumps({'a': 'a'}, ensure_ascii=False)
'{"a": "a"}'
>>> json.dumps({'a': u'a'}, ensure_ascii=False)
u'{"a": "a"}'
>>> json.dumps({'a': 'ä'}, ensure_ascii=False)
'{"a": "\xc3\xa4"}'
>>> json.dumps({u'a': 'ä'}, 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 0xc3 in position 1: ordinal not in range(128)
Run Code Online (Sandbox Code Playgroud)

这个耦合的事实,io.openencoding组只接受unicode对象(这本身是正确的),导致的问题。

返回类型完全取决于if中的键或值的类型ensure_ascii=False,但是str始终返回if ensure_ascii=True。如果您不小心将8位字符串设置为字典,则不能盲目地将此返回类型转换为unicode,因为您需要设置编码,大概是UTF-8:

>>> x = json.dumps(obj, ensure_ascii=False)
>>> if isinstance(x, str):
...     x = unicode(x, 'UTF-8')
Run Code Online (Sandbox Code Playgroud)

这种情况下,我相信您可以使用json.dump写入打开的二进制文件;但是,如果您需要对结果对象进行更复杂的处理,则可能需要上面的代码。


一种解决方案是通过切换到Python 3来消除所有这种编码/解码疯狂。