Aid*_*dis 2 python csv list utf-8 export-to-csv
如何将utf-8字符写入csv文件?
我的数据和代码:
# -*- coding: utf-8 -*-
l1 = ["žžž", "???"]
l2 = ["žžž", "???"]
thelist = [l1, l2]
import csv
import codecs
with codecs.open('test', 'w', "utf-8-sig") as f:
writer = csv.writer(f)
for x in thelist:
print x
for mem in x:
writer.writerow(mem)
Run Code Online (Sandbox Code Playgroud)
错误消息:
Traceback (most recent call last):
File "2010rudeni priimti.py", line 263, in <module>
writer.writerow(mem)
File "C:\Python27\lib\codecs.py", line 691, in write
return self.writer.write(data)
File "C:\Python27\lib\codecs.py", line 351, in write
data, consumed = self.encode(object, self.errors)
File "C:\Python27\lib\encodings\utf_8_sig.py", line 82, in encode
return encode(input, errors)
File "C:\Python27\lib\encodings\utf_8_sig.py", line 15, in encode
return (codecs.BOM_UTF8 + codecs.utf_8_encode(input, errors)[0], len(input))
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc4 in position 11: ordinal not in range(128)
Run Code Online (Sandbox Code Playgroud)
按任意键继续 ...
我的错是什么?
csv2.x中的模块不读取/写入Unicode,它读取/写入字节(并假设它们与ASCII兼容,但这不是UTF-8的问题).
所以,当你给它codecs写一个Unicode文件时,它会传递一个str而不是一个unicode.当codecs尝试使用encodeUTF-8时,它必须首先decode使用Unicode,因为它使用默认编码,即ASCII,它会失败.因此这个错误:
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc4 in position 11: ordinal not in range(128)
Run Code Online (Sandbox Code Playgroud)
该解决方案在文档中进行了解释,示例中的包装器可以为您处理所有事情.使用UnicodeWriter带有普通二进制文件,而不是使用codecs文件.
作为替代方案,PyPI上有一些不同的包csv可以直接处理模块unicode而不是str像unicodecsv.
作为一个更激进的替代方案,Python 3.x的csv模块首先没有这个问题(3.x也没有下一个问题).
一个黑客的替代方案就是假装整个世界都是UTF-8.毕竟,你的源代码和你的输出都是UTF-8,并且csv模块不关心任何东西,只有少数字符(换行符,逗号,可能是引号和反斜杠)是ASCII兼容的.所以你可以完全跳过解码和编码,一切都会好起来的.这里显而易见的缺点是,如果你得到任何错误,而不是得到一个错误来调试,你将得到一个充满垃圾的文件.
您的代码还有另外两个问题,无论是哪个UnicodeWriter还是unicodecsv可以神奇地修复(尽管Python 3可以修复第一个).
首先,你没有真正给了csv摆在首位模块的Unicode.源数据中的列是普通的旧str文字,例如"žžž".您无法将其编码为UTF-8,或者您可以,但只能通过自动将其解码为ascii,这将再次导致相同的错误.使用Unicode文字,比如u"žžž",以避免这种情况(或者,如果您愿意,可以decode从源代码编码中明确表示......但这有点愚蠢).
其次,您没有在源中指定编码声明,但是您使用了非ASCII字符.从技术上讲,这在Python 2.7中是非法的.实际上,我很确定它会给你一个警告,但后来将你的来源视为Latin-1.这很糟糕,因为你显然没有使用Latin-1编辑器(你不能放入žLatin-1文本文件,因为没有这样的字符).如果您将文件保存为UTF-8,然后告诉Python将其解释为Latin-1,那么您最终将使用žžž而不是žžž类似的mojibake.
| 归档时间: |
|
| 查看次数: |
2833 次 |
| 最近记录: |