在Python中创建一个utf-8 csv文件

时间:2010-06-21 13:58:24

标签: python encoding utf-8 csv

我无法在Python中创建utf-8 csv文件。

我正在尝试阅读它的文档,在examples section中,它说:

  

对于所有其他编码如下   UnicodeReader和UnicodeWriter   可以使用类。他们拿了一个   其他编码参数   构造函数,并确保   数据通过真正的读者或作者   编码为UTF-8:

确定。所以我有这个代码:

values = (unicode("Ñ", "utf-8"), unicode("é", "utf-8"))
f = codecs.open('eggs.csv', 'w', encoding="utf-8")
writer = UnicodeWriter(f)
writer.writerow(values)

我一直收到这个错误:

line 159, in writerow
    self.stream.write(data)
  File "/usr/lib/python2.6/codecs.py", line 686, in write
    return self.writer.write(data)
  File "/usr/lib/python2.6/codecs.py", line 351, in write
    data, consumed = self.encode(object, self.errors)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 22: ordinal not in range(128)

有人可以给我一个灯,这样我就可以理解我到底做错了什么,因为我在调用UnicodeWriter类之前到处设置了所有编码?

class UnicodeWriter:
    """
    A CSV writer which will write rows to CSV file "f",
    which is encoded in the given encoding.
    """

    def __init__(self, f, dialect=csv.excel, encoding="utf-8", **kwds):
        # Redirect output to a queue
        self.queue = cStringIO.StringIO()
        self.writer = csv.writer(self.queue, dialect=dialect, **kwds)
        self.stream = f
        self.encoder = codecs.getincrementalencoder(encoding)()

    def writerow(self, row):
        self.writer.writerow([s.encode("utf-8") for s in row])
        # Fetch UTF-8 output from the queue ...
        data = self.queue.getvalue()
        data = data.decode("utf-8")
        # ... and reencode it into the target encoding
        data = self.encoder.encode(data)
        # write to the target stream
        self.stream.write(data)
        # empty queue
        self.queue.truncate(0)

    def writerows(self, rows):
        for row in rows:
            self.writerow(row)

4 个答案:

答案 0 :(得分:14)

您不必使用codecs.open; UnicodeWriter接受Unicode输入并负责将所有内容编码为UTF-8。当UnicodeWriter写入您传递给它的文件句柄时,所有内容都已经采用UTF-8编码(因此它适用于您使用open打开的普通文件)。

通过使用codecs.open,你基本上将你的Unicode对象转换为UnicodeWriter中的UTF-8字符串,然后尝试再次将这些字符串重新编码为UTF-8,就像这些字符串包含Unicode字符串一样,这明显失败了。

答案 1 :(得分:1)

如果您已经发现它可以使用普通打开。

原因是您尝试两次编码UTF-8。进入

f = codecs.open('eggs.csv', 'w', encoding="utf-8")

然后在UnicodeWriter.writeRow

# ... and reencode it into the target encoding
data = self.encoder.encode(data)

要检查这是否有效,请使用原始代码并取消该行。

格尔茨

答案 2 :(得分:1)

我在一段时间后遇到了csv / unicode挑战并将其扔到bitbucket上:http://bitbucket.org/famousactress/dude_csv ..如果您的需求很简单,可能适合您:)

答案 3 :(得分:0)

您无需对所有内容进行“双重编码”。

您的应用程序应完全使用Unicode。

仅在codecs.open中进行编码,以将UTF-8字节写入外部文件。在您的应用程序中不进行其他编码。