csv ---csv文件读写

源代码: Lib/csv.py


所谓的csv(逗号分隔值)格式是电子表格和数据库最常见的导入和导出格式。在尝试用标准化的方式描述格式之前,csv格式已经使用了很多年。 RFC 4180 .缺乏一个定义良好的标准意味着不同应用程序产生和使用的数据中经常存在细微的差异。这些差异可能会使处理来自多个源的csv文件变得烦人。不过,尽管分隔符和引号字符有所不同,但总体格式非常相似,因此可以编写一个模块,该模块可以有效地处理此类数据,从而隐藏从程序员处读取和写入数据的详细信息。

这个 csv 模块实现以csv格式读取和写入表格数据的类。它允许程序员在不知道Excel所使用的csv格式的确切细节的情况下说,“用Excel首选的格式编写数据”,或者“从Excel生成的文件中读取数据”。程序员还可以描述其他应用程序理解的csv格式,或者定义自己的特殊用途csv格式。

这个 csv 模块的 readerwriter 对象读取和写入序列。程序员还可以使用 DictReaderDictWriter 类。

参见

PEP 305 CSV文件API

提出了对python进行此添加的python增强建议。

模块内容

这个 csv 模块定义以下功能:

csv.reader(csvfile, dialect='excel', **fmtparams)

返回一个读卡器对象,该对象将在给定的 CSV文件 . CSV文件 可以是任何支持 iterator 协议,并每次返回一个字符串 __next__() 方法被调用--- file objects 列表对象都是合适的。如果 CSV文件 是一个文件对象,应该用 newline='' . 1 可选的 方言 可以指定参数,该参数用于定义特定于特定csv方言的一组参数。它可能是 Dialect 类或由返回的字符串之一 list_dialects() 功能。另一个可选 FMTPARAMS 可以提供关键字参数来覆盖当前方言中的各个格式参数。有关方言和格式参数的完整详细信息,请参见第节 方言和格式参数 .

从csv文件读取的每一行都作为字符串列表返回。除非 QUOTE_NONNUMERIC 指定格式选项(在这种情况下,未加引号的字段将转换为浮点数)。

简短用法示例:

>>> import csv
>>> with open('eggs.csv', newline='') 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
csv.writer(csvfile, dialect='excel', **fmtparams)

返回一个编写器对象,该对象负责将用户的数据在给定的类似文件的对象上转换为带分隔符的字符串。 CSV文件 可以是任何具有 write() 方法。如果 CSV文件 是一个文件对象,应该用 newline='' 1. 可选的 方言 可以指定参数,该参数用于定义特定于特定csv方言的一组参数。它可能是 Dialect 类或由返回的字符串之一 list_dialects() 功能。另一个可选 FMTPARAMS 可以提供关键字参数来覆盖当前方言中的各个格式参数。有关方言和格式参数的完整详细信息,请参见第节 方言和格式参数 . 为了尽可能容易地与实现DBAPI的模块进行接口,值 None 写为空字符串。虽然这不是可逆转换,但它使将SQL空数据值转储到csv文件更容易,而无需预处理从 cursor.fetch* 调用。所有其他非字符串数据都用字符串化 str() 在被写之前。

简短用法示例:

import csv
with open('eggs.csv', 'w', newline='') 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'])
csv.register_dialect(name[, dialect[, **fmtparams]])

联想 方言 具有 name . name 必须是字符串。可以通过传递 Dialect ,或 FMTPARAMS 关键字参数,或两者兼而有之,关键字参数将覆盖方言的参数。有关方言和格式参数的完整详细信息,请参见第节 方言和格式参数 .

csv.unregister_dialect(name)

删除与关联的方言 name 来自方言注册表。安 Error 如果 name 不是已注册的方言名。

csv.get_dialect(name)

返回与关联的方言 name . 安 Error 如果 name 不是已注册的方言名。此函数返回不可变的 Dialect .

csv.list_dialects()

返回所有已注册方言的名称。

csv.field_size_limit([new_limit])

返回分析程序允许的当前最大字段大小。如果 new_limit 如果给定,这将成为新的限制。

这个 csv 模块定义以下类:

class csv.DictReader(f, fieldnames=None, restkey=None, restval=None, dialect='excel', *args, **kwds)

创建一个像普通阅读器一样工作但将每行中的信息映射到 dict 其密钥由可选项提供 字段名 参数。

这个 字段名 参数是 sequence . 如果 字段名 省略,文件第一行中的值 f 将用作字段名。不管字段名是如何确定的,字典都会保留其原始顺序。

如果一行中的字段多于字段名,则剩余数据将放入列表中,并使用由指定的字段名存储。 赖斯基 (默认为 None ). 如果非空行的字段少于字段名,则用 赖斯瓦尔 (默认为 None

所有其他可选参数或关键字参数都传递给基础 reader 实例。

在 3.6 版更改: 返回的行现在属于类型 OrderedDict .

在 3.8 版更改: 返回的行现在属于类型 dict .

简短用法示例:

>>> import csv
>>> with open('names.csv', newline='') as csvfile:
...     reader = csv.DictReader(csvfile)
...     for row in reader:
...         print(row['first_name'], row['last_name'])
...
Eric Idle
John Cleese

>>> print(row)
{'first_name': 'John', 'last_name': 'Cleese'}
class csv.DictWriter(f, fieldnames, restval='', extrasaction='raise', dialect='excel', *args, **kwds)

创建一个像常规编写器一样工作但将字典映射到输出行的对象。这个 字段名 参数是 sequence 标识字典中的值传递给 writerow() 方法写入文件 f . 可选的 赖斯瓦尔 参数指定字典中缺少键时要写入的值。 字段名 . 如果字典传递给 writerow() 方法包含在中找不到的键 字段名 ,可选的 超量作用 参数指示要采取的操作。如果设置为 'raise' ,默认值,A ValueError 被引发。如果设置为 'ignore' ,字典中的额外值将被忽略。将任何其他可选参数或关键字参数传递给基础 writer 实例。

注意,与 DictReader字段名 的参数 DictWriter 类不是可选的。

简短用法示例:

import csv

with open('names.csv', 'w', newline='') 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'})
class csv.Dialect

这个 Dialect 类是主要依赖于其属性的容器类,用于定义特定 readerwriter 实例。

class csv.excel

这个 excel 类定义Excel生成的csv文件的常规属性。它是用方言名注册的 'excel' .

class csv.excel_tab

这个 excel_tab 类定义Excel生成的以制表符分隔的文件的常规属性。它是用方言名注册的 'excel-tab' .

class csv.unix_dialect

这个 unix_dialect 类定义在UNIX系统上生成的csv文件的常规属性,即使用 '\n' 作为行终止符并引用所有字段。它是用方言名注册的 'unix' .

3.2 新版功能.

class csv.Sniffer

这个 Sniffer 类用于推断csv文件的格式。

这个 Sniffer 类提供了两种方法:

sniff(sample, delimiters=None)

分析给定的 样品 并返回 Dialect 反映所找到参数的子类。如果可选 delimiters 参数,它被解释为包含可能有效分隔符字符的字符串。

has_header(sample)

分析示例文本(假定为csv格式)并返回 True 如果第一行显示为一系列列标题。

例如 Sniffer 用途:

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

这个 csv 模块定义以下常量:

csv.QUOTE_ALL

指导 writer 对象引用所有字段。

csv.QUOTE_MINIMAL

指导 writer 对象只引用包含特殊字符的字段,如 定界符夸特尔 或中的任何字符 直线加速器 .

csv.QUOTE_NONNUMERIC

指导 writer 对象引用所有非数字字段。

指示读者将所有非引号字段转换为类型 浮动 .

csv.QUOTE_NONE

指导 writer 不引用字段的对象。当电流 定界符 在输出数据中发生,其前面是当前 逃逸者 性格。如果 逃逸者 未设置,作者将引发 Error 如果遇到任何需要转义的字符。

指导 reader 不执行引号字符的特殊处理。

这个 csv 模块定义以下异常:

exception csv.Error

当检测到错误时由任何函数引发。

方言和格式参数

为了更容易指定输入和输出记录的格式,特定的格式参数被分组到方言中。方言是 Dialect 具有一组特定方法和一个 validate() 方法。创建时 readerwriter 对象,程序员可以指定 Dialect 类作为方言参数。除了或代替 方言 参数,程序员还可以指定单独的格式化参数,这些参数与下面为 Dialect 类。

方言支持以下属性:

Dialect.delimiter

用于分隔字段的一个字符串。它默认为 ',' .

Dialect.doublequote

控制的实例 夸特尔 出现在字段中的内容本身也应该被引用。什么时候? True ,字符翻倍。什么时候? False , the 逃逸者 用作 夸特尔 . 它默认为 True .

关于输出,如果 双引号False 而且没有 逃逸者 已设置, Error 如果是 夸特尔 在字段中找到。

Dialect.escapechar

由编写器用于转义 定界符 如果 报价 设置为 QUOTE_NONE 以及 夸特尔 如果 双引号False .关于阅读, 逃逸者 删除以下字符的任何特殊含义。它默认为 None ,这将禁用转义。

Dialect.lineterminator

用于终止由 writer . 它默认为 '\r\n' .

注解

这个 reader 硬编码以识别 '\r''\n' 作为行尾,忽略 直线加速器 . 这种行为将来可能会改变。

Dialect.quotechar

一个单字符字符串,用于引用包含特殊字符的字段,如 定界符夸特尔 或包含新行字符的。它默认为 '"' .

Dialect.quoting

控制何时由作者生成报价并由读者识别。它可以承受任何 QUOTE_* 常数(见第节 模块内容 )默认为 QUOTE_MINIMAL .

Dialect.skipinitialspace

什么时候? True ,空格紧跟 定界符 被忽略。默认值为 False .

Dialect.strict

什么时候? True ,引发异常 Error 在错误的csv输入上。默认值为 False .

读者对象

读者对象 (DictReader 由返回的实例和对象 reader() 功能)具有以下公共方法:

csvreader.__next__()

将读卡器的iterable对象的下一行作为列表返回(如果该对象是从 reader() )或者听写(如果是 DictReader 实例),根据当前方言进行分析。通常你应该把这个叫做 next(reader) .

读卡器对象具有以下公共属性:

csvreader.dialect

解析器正在使用的方言的只读描述。

csvreader.line_num

从源迭代器读取的行数。这与返回的记录数不同,因为记录可以跨多行。

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

csvreader.fieldnames

如果在创建对象时未作为参数传递,则在第一次访问或从文件中读取第一条记录时初始化此属性。

写入对象

Writer 物体 (DictWriter 由返回的实例和对象 writer() 函数)具有以下公共方法。A row 必须是字符串或数字的iteable for Writer 对象和将字段名映射到字符串或数字的字典(通过传递它们 str() 第一) DictWriter 物体。注意复数是用parens括起来的。这可能会给其他读取csv文件的程序带来一些问题(假设它们支持复杂的数字)。

csvwriter.writerow(row)

写下 row 写入程序文件对象的参数,根据当前方言设置格式。将调用的返回值返回到 基础文件对象的方法。

在 3.5 版更改: 增加了对任意iterables的支持。

csvwriter.writerows(rows)

将所有元素写入 rows (可迭代的 row 对象(如上所述)到编写器的文件对象,按照当前方言格式化。

编写器对象具有以下公共属性:

csvwriter.dialect

作者使用的方言的只读描述。

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

DictWriter.writeheader()

将字段名为(在构造函数中指定的)的行写入编写器的文件对象,并根据当前方言格式化。返回的返回值 csvwriter.writerow() 内部使用的呼叫。

3.2 新版功能.

在 3.8 版更改: writeheader() 现在还返回 csvwriter.writerow() 它在内部使用的方法。

实例

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

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

读取具有备用格式的文件::

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

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

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

自从 open() 用于打开要读取的csv文件,默认情况下,该文件将使用系统默认编码解码为Unicode(请参见 locale.getpreferredencoding() )要使用其他编码解码文件,请使用 encoding 打开参数:

import csv
with open('some.csv', newline='', encoding='utf-8') as f:
    reader = csv.reader(f)
    for row in reader:
        print(row)

这同样适用于以系统默认编码以外的方式写入:打开输出文件时指定编码参数。

注册新方言:

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

读卡器的一种更高级的用法——捕获和报告错误:

import csv, sys
filename = 'some.csv'
with open(filename, newline='') as f:
    reader = csv.reader(f)
    try:
        for row in reader:
            print(row)
    except csv.Error as e:
        sys.exit('file {}, line {}: {}'.format(filename, reader.line_num, e))

虽然模块不直接支持解析字符串,但很容易做到:

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

脚注

1(1,2)

如果 newline='' 未指定,在引用字段中嵌入的换行将无法正确解释,并且在使用 \r\n 写一个额外的 \r 将添加。应该总是安全地指定 newline='' ,因为csv模块本身 (universal )换行处理。