这里最可能的问题是它json_obj["description"]实际上是 UTF-8 编码的str,而不是unicode. 因此,当您尝试将write其转换为codecs-wrapped 文件时,Python 必须将其从strto解码,unicode以便重新对其进行编码。这就是失败的部分,因为自动解码使用sys.getdefaultencoding()的是'ascii'.
例如:
>>> f = codecs.open('emoji.txt', 'w+', encoding='utf-8')
>>> e = u'\U0001f1ef'
>>> print e
>>> e
u'\U0001f1ef'
>>> f.write(e)
>>> e8 = e.encode('utf-8')
>>> e8
'\xf0\x9f\x87\xaf'
>>> f.write(e8)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xf0 in position 0: ordinal not in range(128)
这里有两种可能的解决方案。
首先,您可以unicode尽早明确解码所有内容。我不确定你json_obj来自哪里,但我怀疑它实际上不是 stdlib json.loads,因为默认情况下,它总是给你unicode键和值。因此,将您用于 JSON 的任何内容替换为 stdlib 函数可能会解决问题。
其次,您可以将所有内容保留为 UTF-8str对象并保持二进制模式。如果您知道到处都有 UTF-8,只需open使用文件而不是codecs.open, 并且无需任何编码即可写入。
此外,您应该强烈考虑使用io.open而不是codecs.open. 它有许多优点,包括:
- 如果您传递不正确的值,则引发异常而不是做错事。
- 通常更快。
- 与 Python 3 前向兼容。
- 有许多永远不会被向后移植到
codecs.
唯一的缺点是它不向后兼容 Python 2.5。除非这对您很重要,否则不要使用codecs.