在Python中创建utf-8的csv文件

17 投票
4 回答
20711 浏览
提问于 2025-04-16 00:14

我在Python中无法创建一个utf-8编码的csv文件。

我在查看相关文档,在示例部分,它提到:

对于其他所有编码,可以使用以下的 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 个回答

1

我之前遇到过关于csv和unicode的问题,所以在bitbucket上放了一个项目:http://bitbucket.org/famousactress/dude_csv。如果你的需求比较简单,这个可能对你有帮助哦 :)

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)

要确认这个问题,可以用你原来的代码,把那一行注释掉。

祝好!

14

你不需要使用 codecs.openUnicodeWriter 可以直接处理 Unicode 输入,并且会自动把所有内容编码成 UTF-8。当 UnicodeWriter 把内容写入你提供的文件时,所有内容已经是 UTF-8 编码了(所以它可以和你用 open 打开的普通文件一起使用)。

如果你使用 codecs.open,实际上你是在把 Unicode 对象转换成 UTF-8 字符串,然后又试图把这些字符串重新编码成 UTF-8,就好像这些字符串本身是 Unicode 字符串一样,这显然是行不通的。

撰写回答