使用Python2.x unicodecsv时出现UnicodeCodeError

使用Python2.x unicodecsv时出现UnicodeCodeError,python,unicode,python-unicode,Python,Unicode,Python Unicode,我试图用Unicode字符写出一个csv文件,所以我使用Unicode decsv包。不幸的是,我仍然收到UnicodeDecors错误: # -*- coding: utf-8 -*- import codecs import unicodecsv raw_contents = 'He observes an “Oversized Gorilla” near Ashford' encoded_contents = unicode(raw_contents, errors='replace'

我试图用Unicode字符写出一个csv文件,所以我使用Unicode decsv包。不幸的是,我仍然收到UnicodeDecors错误:

# -*- coding: utf-8 -*-

import codecs
import unicodecsv

raw_contents = 'He observes an “Oversized Gorilla” near Ashford'
encoded_contents = unicode(raw_contents, errors='replace')

with codecs.open('test.csv', 'w', 'UTF-8') as f:
    w = unicodecsv.writer(f, encoding='UTF-8')
    w.writerow(["1", encoded_contents])
这是回溯:

Traceback (most recent call last):
  File "unicode_test.py", line 11, in <module>
    w.writerow(["1", encoded_contents])
  File "/Library/Python/2.7/site-packages/unicodecsv/__init__.py", line 83, in writerow
    self.writer.writerow(_stringify_list(row, self.encoding, self.encoding_errors))
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/codecs.py", line 691, in write
    return self.writer.write(data)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/codecs.py", line 351, in write
    data, consumed = self.encode(object, self.errors)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xef in position 17: ordinal not in range(128)
回溯(最近一次呼叫最后一次):
文件“unicode_test.py”,第11行,在
w、 writerow([“1”,编码内容])
文件“/Library/Python/2.7/site packages/unicodesv/_init__uuu.py”,第83行,writerow格式
self.writer.writerow(_stringify_列表(行、self.encoding、self.encoding_错误))
文件“/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/codecs.py”,第691行,以书面形式
返回self.writer.write(数据)
文件“/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/codecs.py”,第351行,以书面形式
数据,消耗=self.encode(对象,self.errors)
UnicodeDecodeError:“ascii”编解码器无法解码位置17中的字节0xef:序号不在范围内(128)
我认为将其转换为Unicode就足够了,但事实似乎并非如此。我真的很想了解正在发生的事情,以便更好地准备在将来的其他项目中处理这些错误

从回溯来看,我似乎可以重现如下错误:

>>> raw_contents = 'He observes an “Oversized Gorilla” near Ashford'
>>> raw_contents.encode('UTF-8')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe2 in position 15: ordinal not in range(128)
>>> 
原始内容='他在阿什福德附近观察到一只“超大的大猩猩” >>>原始内容编码('UTF-8') 回溯(最近一次呼叫最后一次): 文件“”,第1行,在 UnicodeDecodeError:“ascii”编解码器无法解码位置15中的字节0xe2:序号不在范围内(128) >>> 到目前为止,我还以为自己对Python 2.x中的Unicode文本有很好的使用知识,但这让我感到惭愧。

您不应该对文件使用
codecs.open()
unicodesv
包装
csv
模块,该模块始终将字节字符串写入打开的文件对象。为了将该字节字符串写入支持Unicode的文件对象,例如由
codecs.open()
返回的文件对象,它被隐式解码;这就是您的
UnicodeDecodeError
异常产生的原因

改为使用二进制模式的文件:

with open('test.csv', 'wb') as f:
    w = unicodecsv.writer(f, encoding='UTF-8')
    w.writerow(["1", encoded_contents])
除非数据包含嵌入的换行符,否则二进制模式并非绝对必要,但
csv
模块希望控制换行符的写入方式,以确保正确处理此类值。但是,绝对要求不使用
编解码器.open()


对字节字符串调用
.encode()
时也会发生同样的情况;您已经在那里对数据进行了编码,因此Python隐式解码以获得要编码的Unicode值。

FYI:
encoded\u contents
是一个误导性的名称
unicode\u text.encode(char\u编码)=字节数据
,反之为
bytes\u数据。decode(char\u编码)==unicode\u文本
encoded_contents
错误地表明它是一个
bytes
对象,而不是
unicode
这是正确的,但文件对象(对于支持unicode的插入式csv模块替换)应该是二进制的并不明显。它需要一个二进制文件,因为
unicodesv
是一个围绕
csv
模块的薄型包装器,只能在Python 2上处理二进制数据。否则,也可以为文本流定义csv格式(如JSON)。但是,不使用编解码器。open()是绝对要求==
u'unicode示例。编码('utf-8')
==
UnicodeDecodeError
?@SIslam:如果所有数据都是ASCII安全的(它将被解码为ASCII,而不是
utf-8
),然后你就可以不用使用
编解码器了。open()
。然而,这是非常无用的;您可以只使用常规文件,而不是Python来执行无用的解码-编码舞蹈。