使用Python2.x unicodecsv时出现UnicodeCodeError
我试图用Unicode字符写出一个csv文件,所以我使用Unicode decsv包。不幸的是,我仍然收到UnicodeDecors错误:使用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'
# -*- 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来执行无用的解码-编码舞蹈。