将utf-8格式的Python列表编写为CSV

 邹杂品_433 发布于 2023-02-02 19:22

如何将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) 

错误消息:

Traceback (most recent call last):
   File "2010rudeni priimti.py", line 263, in 
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)

按任意键继续 ...

我的错是什么?

1 个回答
  • 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)
    

    该解决方案在文档中进行了解释,示例中的包装器可以为您处理所有事情.使用UnicodeWriter带有普通二进制文件,而不是使用codecs文件.


    作为替代方案,PyPI上有一些不同的包csv可以直接处理模块unicode而不是strunicodecsv.

    作为一个更激进的替代方案,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.

    2023-02-02 19:26 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有