13.1. csv — CSV 文件读写

2.3 版的新Function。

所谓的 CSV(逗号分隔值)格式是电子表格和数据库最常用的导入和导出格式。由于没有“ CSV 标准”,因此该格式由许多读写该应用程序的应用程序定义。缺乏标准意味着由不同应用程序生成和使用的数据通常存在细微差异。这些差异会使处理来自多个来源的 CSV 文件变得烦人。尽管如此,尽管定界符和引号字符有所不同,但总体格式足够相似,因此有可能编写一个可以有效处理此类数据的模块,从而隐藏了对程序员进行数据读写的细节。

csv模块实现用于以 CSV 格式读取和写入表格数据的类。它使程序员可以说“以 Excel 首选的格式写入此数据”或“从 Excel 生成的此文件中读取数据”,而无需知道 Excel 所使用的 CSV 格式的确切细节。程序员还可以描述其他应用程序可以理解的 CSV 格式,或者定义自己的专用 CSV 格式。

csv模块的readerwriter对象读取和写入序列。程序员还可以使用DictReaderDictWriter类以字典形式读取和写入数据。

Note

此版本的csv模块不支持 UnicodeImporting。另外,当前还存在一些有关 ASCII NUL 字符的问题。因此,所有 Importing 均应为 UTF-8 或可打印的 ASCII,以确保安全;请参阅Examples部分中的示例。

See also

  • PEP 305-CSV 文件 API

  • 《 Python 增强提案》提出了对 Python 的这一补充。

13.1.1. 模块内容

csv模块定义以下Function:

从 csv 文件读取的每一行都作为字符串列表返回。不执行自动数据类型转换。

一个简短的用法示例:

>>> import csv
>>> with open('eggs.csv', 'rb') as csvfile:
...     spamreader = csv.reader(csvfile, delimiter=' ', quotechar='|')
...     for row in spamreader:
...         print ', '.join(row)
Spam, Spam, Spam, Spam, Spam, Baked Beans
Spam, Lovely Spam, Wonderful Spam

在版本 2.5 中进行了更改:现在,对于多行引用字段,解析器更加严格。以前,如果一行在带引号的字段中结束但没有换行符终止,则将换行符插入返回的字段中。读取字段中包含回车符的文件时,此行为导致问题。行为已更改为不插入换行符即可返回该字段。因此,如果嵌入在字段中的换行很重要,则应以保留换行符的方式将 Importing 分成几行。

一个简短的用法示例:

import csv
with open('eggs.csv', 'wb') as csvfile:
    spamwriter = csv.writer(csvfile, delimiter=' ',
                            quotechar='|', quoting=csv.QUOTE_MINIMAL)
    spamwriter.writerow(['Spam'] * 5 + ['Baked Beans'])
    spamwriter.writerow(['Spam', 'Lovely Spam', 'Wonderful Spam'])

在版本 2.5 中更改:此函数现在返回一个不可变的Dialect。以前,返回了所请求方言的一个实例。用户可以修改基础类,从而更改活动的读取器和写入器的行为。

2.5 版的新Function。

csv模块定义以下类别:

一个简短的用法示例:

>>> import csv
>>> with open('names.csv') as csvfile:
...     reader = csv.DictReader(csvfile)
...     for row in reader:
...         print(row['first_name'], row['last_name'])
...
Baked Beans
Lovely Spam
Wonderful Spam

请注意,与DictReader类不同,DictWriter的* fieldnames 参数不是可选的。由于未对 Python 的dict对象进行排序,因此没有足够的信息来推断应将行写入文件 f *的 Sequences。

一个简短的用法示例:

import csv

with open('names.csv', 'w') as csvfile:
    fieldnames = ['first_name', 'last_name']
    writer = csv.DictWriter(csvfile, fieldnames=fieldnames)

    writer.writeheader()
    writer.writerow({'first_name': 'Baked', 'last_name': 'Beans'})
    writer.writerow({'first_name': 'Lovely', 'last_name': 'Spam'})
    writer.writerow({'first_name': 'Wonderful', 'last_name': 'Spam'})

Sniffer类提供了两种方法:

Sniffer使用的示例:

with open('example.csv', 'rb') as csvfile:
    dialect = csv.Sniffer().sniff(csvfile.read(1024))
    csvfile.seek(0)
    reader = csv.reader(csvfile, dialect)
    # ... process CSV file contents here ...

csv模块定义以下常量:

指示 Reader 将所有未引用的字段转换为* float *类型。

指示reader不对引号字符进行特殊处理。

csv模块定义以下异常:

13.1.2. 方言和格式参数

为了更轻松地指定 Importing 和输出记录的格式,将特定的格式设置参数组合为方言。方言是Dialect类的子类,它具有一组特定方法和一个validate()方法。创建readerwriter对象时,程序员可以将字符串或Dialect类的子类指定为方言参数。除了* dialect *参数以外,程序员还可以指定各个格式设置参数,这些参数的名称与下面为Dialect类定义的属性相同。

方言支持以下属性:

在输出时,如果* doublequote False且未设置 escapechar ,则如果在字段中找到 quotechar *,则引发Error

Note

reader被硬编码为将'\r''\n'识别为行尾,并忽略* lineterminator *。这种行为将来可能会改变。

13.1.3. Reader 对象

阅读器对象(DictReader实例和reader()函数返回的对象)具有以下公共方法:

Reader 对象具有以下公共属性:

2.5 版的新Function。

DictReader 对象具有以下公共属性:

在 2.6 版中进行了更改。

13.1.4. Writer 对象

Writer个对象(DictWriter个实例和writer()函数返回的对象)具有以下公共方法。 必须是Writer对象的字符串或数字序列,并且是将DictWriter对象的字段名 Map 为字符串或数字(首先passstr()传递)的字典。请注意,复数写在括号内。这可能会给其他读取 CSV 文件的程序带来一些问题(假设它们完全支持复数)。

Writer 对象具有以下公共属性:

DictWriter 对象具有以下公共方法:

2.7 版的新Function。

13.1.5. Examples

读取 CSV 文件的最简单示例:

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

读取具有其他格式的文件:

import csv
with open('passwd', 'rb') as f:
    reader = csv.reader(f, delimiter=':', quoting=csv.QUOTE_NONE)
    for row in reader:
        print row

相应的最简单的编写示例是:

import csv
with open('some.csv', 'wb') as f:
    writer = csv.writer(f)
    writer.writerows(someiterable)

注册新的方言:

import csv
csv.register_dialect('unixpwd', delimiter=':', quoting=csv.QUOTE_NONE)
with open('passwd', 'rb') as f:
    reader = csv.reader(f, 'unixpwd')

阅读器的更高级用法-捕获并报告错误:

import csv, sys
filename = 'some.csv'
with open(filename, 'rb') as f:
    reader = csv.reader(f)
    try:
        for row in reader:
            print row
    except csv.Error as e:
        sys.exit('file %s, line %d: %s' % (filename, reader.line_num, e))

尽管该模块不直接支持解析字符串,但可以轻松实现:

import csv
for row in csv.reader(['one,two,three']):
    print row

csv模块不直接支持读写 Unicode,但是它是 8 位纯净的,除了 ASCII NUL 字符的某些问题。因此,只要避免使用 NUL 的 UTF-16 之类的编码,就可以编写为您处理编码和解码的函数或类。建议使用 UTF-8.

下面的unicode_csv_reader()generator,它包装csv.reader以处理 Unicode CSV 数据(Unicode 字符串列表)。 utf_8_encoder()generator,它将 Unicode 字符串编码为 UTF-8,一次编码一个字符串(或一行)。编码的字符串由 CSV 阅读器解析,并且unicode_csv_reader()将 UTF-8 编码的单元解码回 Unicode:

import csv

def unicode_csv_reader(unicode_csv_data, dialect=csv.excel, **kwargs):
    # csv.py doesn't do Unicode; encode temporarily as UTF-8:
    csv_reader = csv.reader(utf_8_encoder(unicode_csv_data),
                            dialect=dialect, **kwargs)
    for row in csv_reader:
        # decode UTF-8 back to Unicode, cell by cell:
        yield [unicode(cell, 'utf-8') for cell in row]

def utf_8_encoder(unicode_csv_data):
    for line in unicode_csv_data:
        yield line.encode('utf-8')

对于所有其他编码,可以使用以下UnicodeReaderUnicodeWriter类。他们在构造函数中采用了额外的* encoding *参数,并确保数据pass编码为 UTF-8 的真实读取器或写入器:

import csv, codecs, cStringIO

class UTF8Recoder:
    """
    Iterator that reads an encoded stream and reencodes the input to UTF-8
    """
    def __init__(self, f, encoding):
        self.reader = codecs.getreader(encoding)(f)

    def __iter__(self):
        return self

    def next(self):
        return self.reader.next().encode("utf-8")

class UnicodeReader:
    """
    A CSV reader which will iterate over lines in the CSV file "f",
    which is encoded in the given encoding.
    """

    def __init__(self, f, dialect=csv.excel, encoding="utf-8", **kwds):
        f = UTF8Recoder(f, encoding)
        self.reader = csv.reader(f, dialect=dialect, **kwds)

    def next(self):
        row = self.reader.next()
        return [unicode(s, "utf-8") for s in row]

    def __iter__(self):
        return self

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)
首页