这里最可能的问题是它json_obj["description"]
实际上是 UTF-8 编码的str
,而不是unicode
. 因此,当您尝试将write
其转换为codecs
-wrapped 文件时,Python 必须将其从str
to解码,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
.