Python 2.6中的CSV文件通用Unicode/UTF-8支持

43 投票
10 回答
29138 浏览
提问于 2025-04-15 16:41

Python中的csv模块在处理UTF-8或Unicode时常常会出现问题。我在Python文档和其他网页上找到了一些适用于特定情况的代码片段,但你需要非常清楚自己在处理什么编码,并使用合适的代码片段。

我该如何在Python 2.6中读取和写入字符串和Unicode字符串的.csv文件,才能做到“直接就能用”?还是说这是Python 2.6的一个限制,没有简单的解决办法?

10 个回答

22

这里提供的模块链接,看起来是一个很不错、简单的替代品,可以替换掉csv模块,让你能够使用utf-8编码的csv文件。

import ucsv as csv
with open('some.csv', 'rb') as f:
    reader = csv.reader(f)
    for row in reader:
        print row
32

虽然回答得有点晚,但我用过 unicodecsv,效果非常好。

52

在这个链接 http://docs.python.org/library/csv.html#examples 上提供的关于如何读取Unicode的示例代码似乎已经过时,因为它在Python 2.6和2.7中无法使用。

接下来是一个叫做 UnicodeDictReader 的东西,它可以处理utf-8编码,可能也能处理其他编码,但我只在utf-8的输入上测试过。

简单来说,这个方法的核心思想是,在用 csv.reader 把csv的一行数据分割成各个字段后,再进行Unicode解码。

class UnicodeCsvReader(object):
    def __init__(self, f, encoding="utf-8", **kwargs):
        self.csv_reader = csv.reader(f, **kwargs)
        self.encoding = encoding

    def __iter__(self):
        return self

    def next(self):
        # read and split the csv row into fields
        row = self.csv_reader.next() 
        # now decode
        return [unicode(cell, self.encoding) for cell in row]

    @property
    def line_num(self):
        return self.csv_reader.line_num

class UnicodeDictReader(csv.DictReader):
    def __init__(self, f, encoding="utf-8", fieldnames=None, **kwds):
        csv.DictReader.__init__(self, f, fieldnames=fieldnames, **kwds)
        self.reader = UnicodeCsvReader(f, encoding=encoding, **kwds)

使用方法(源文件编码为utf-8):

csv_lines = (
    "абв,123",
    "где,456",
)

for row in UnicodeCsvReader(csv_lines):
    for col in row:
        print(type(col), col)

输出结果:

$ python test.py
<type 'unicode'> абв
<type 'unicode'> 123
<type 'unicode'> где
<type 'unicode'> 456

撰写回答