14.1. csv
— CSV文件读写¶
源代码: Lib/csv.py
所谓的CSV(逗号分隔值)格式是电子表格和数据库最常见的导入和导出格式。 CSV格式在尝试以 RFC 4180 中的标准化方式描述格式之前使用多年。缺乏明确定义的标准意味着在不同应用产生和消费的数据中通常存在细微的差异。这些差异可能会让处理来自多个来源的CSV文件烦人。尽管分隔符和引用字符不同,但是整体格式是足够相似的,以致于可以编写能够有效地操作这样的数据的单个模块,隐藏从编程器读取和写入数据的细节。
csv
模块实现以CSV格式读取和写入表格数据的类。它允许程序员说,“以Excel首选的格式写入数据”或“从Excel生成的此文件中读取数据”,而不知道Excel使用的CSV格式的确切详细信息。程序员还可以描述其他应用程序理解的CSV格式,或定义自己的特殊用途CSV格式。
csv
模块的 reader
和 writer
对象读取和写入序列。程序员还可以使用 DictReader
和 DictWriter
类以字典形式读取和写入数据。
参见
- PEP 305 - CSV文件API
Python Enhancement Proposal提出了对Python的添加。
14.1.1. 模块内容¶
csv
模块定义以下功能:
-
csv.
reader
(csvfile, dialect='excel', **fmtparams)¶ 返回一个读者对象,它将迭代给定的 csvfile 中的行。 csvfile 可以是支持 iterator 协议并且每次调用
__next__()
方法时返回字符串的任何对象— 文件对象 和列表对象都是合适的。如果 csvfile 是文件对象,则应使用newline=''
打开。 [1] 可以给出一个可选的 dialect 参数,用于定义特定于某个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)¶ 返回一个writer对象,负责将用户的数据转换为给定类文件对象上的分隔字符串。 csvfile 可以是具有
write()
方法的任何对象。如果 csvfile 是一个文件对象,它应该用newline=''
[1] 打开。可以给出可选的 dialect 参数,其用于定义特定于特定CSV方言的一组参数。它可以是Dialect
类的子类的实例或者list_dialects()
函数返回的字符串之一。可以给出其他可选的 fmtparams 关键字参数来覆盖当前方言中的各个格式化参数。有关方言和格式化参数的完整详细信息,请参见 方言和格式化参数 部分。为了尽可能容易地与实现DB API的模块接口,值None
被写为空字符串。虽然这不是一个可逆的转换,它使得更容易转储SQL NULL数据值到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]])¶ 将 dialect 与 name 相关联。 name 必须是字符串。方言可以通过传递
Dialect
的子类或 fmtparams 关键字参数或两者,用关键字参数覆盖方言的参数来指定。有关方言和格式参数的完整详细信息,请参阅 方言和格式化参数 一节。
-
csv.
list_dialects
()¶ 返回所有注册方言的名称。
-
csv.
field_size_limit
([new_limit])¶ 返回解析器允许的当前最大字段大小。如果给出 new_limit,这将成为新的限制。
csv
模块定义以下类:
-
class
csv.
DictReader
(csvfile, fieldnames=None, restkey=None, restval=None, dialect='excel', *args, **kwds)¶ 创建一个像常规阅读器一样操作的对象,但将每行中的信息映射到
OrderedDict
,其键由可选的 fieldnames 参数给出。fieldnames 参数是 sequence。如果省略 fieldnames,则 csvfile 第一行中的值将用作字段名称。无论如何确定字段名,有序字典保留其原始排序。
如果行的字段数多于字段名称,则剩余数据将被放入列表中,并使用由 restkey (默认为
None
)指定的字段名称存储。如果非空行的字段少于字段名,则缺少的值将使用None
填充。所有其他可选或关键字参数传递给基础
reader
实例。在 3.6 版更改: 返回的行现在是
OrderedDict
类型。一个简短的用法示例:
>>> import csv >>> with open('names.csv') as csvfile: ... reader = csv.DictReader(csvfile) ... for row in reader: ... print(row['first_name'], row['last_name']) ... Eric Idle John Cleese >>> print(row) OrderedDict([('first_name', 'John'), ('last_name', 'Cleese')])
-
class
csv.
DictWriter
(csvfile, fieldnames, restval='', extrasaction='raise', dialect='excel', *args, **kwds)¶ 创建一个像普通的writer一样操作的对象,但把字典映射到输出行上。 fieldnames 参数是键的
sequence
,其标识传递给writerow()
方法的字典中的值被写入 csvfile 的顺序。如果字典在 fieldnames 中缺少键,则可选的 restval 参数指定要写入的值。如果传递给writerow()
方法的字典包含在 fieldnames 中未找到的键,则可选的 extrasaction 参数指示要采取的操作。如果设置为'raise'
,则默认值为ValueError
。如果设置为'ignore'
,则字典中的额外值将被忽略。任何其他可选或关键字参数传递给底层writer
实例。注意,与
DictReader
类不同,DictWriter
的 fieldnames 参数不是可选的。由于Python的dict
对象没有排序,因此没有足够的信息来推断应该将行写入 csvfile 的顺序。一个简短的用法示例:
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'})
-
class
csv.
unix_dialect
¶ unix_dialect
类定义在UNIX系统上生成的CSV文件的通常属性,即使用'\n'
作为行终止符并引用所有字段。它用方言名称'unix'
注册。3.2 新版功能.
-
class
csv.
Sniffer
¶ Sniffer
类用于推导CSV文件的格式。Sniffer
类提供两种方法:
Sniffer
使用的一个例子:
with open('example.csv') 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_NONE
¶ 指示
writer
对象从不引用字段。当输出数据中出现当前 delimiter 时,其前面是当前 escapechar 字符。如果未设置 escapechar,则在遇到需要转义的任何字符时,写入程序将提高Error
。指示
reader
不执行引号字符的特殊处理。
csv
模块定义了以下异常:
-
exception
csv.
Error
¶ 检测到错误时由任何函数引发。
14.1.2. 方言和格式化参数¶
为了更容易指定输入和输出记录的格式,特定的格式化参数被分组到方言中。方言是 Dialect
类的子类,具有一组特定方法和单个 validate()
方法。当创建 reader
或 writer
对象时,程序员可以指定 Dialect
类的字符串或子类作为方言参数。除了或替代 dialect 参数,程序员还可以指定单独的格式化参数,其具有与下面针对 Dialect
类定义的属性相同的名称。
方言支持以下属性:
-
Dialect.
delimiter
¶ 用于分隔字段的单字符字符串。它默认为
','
。
-
Dialect.
doublequote
¶ 控制在字段中出现的 quotechar 的实例本身应如何引用。当
True
时,字符加倍。当False
时,escapechar 用作 quotechar 的前缀。它默认为True
。在输出上,如果 doublequote 是
False
并且没有设置 escapechar,则如果在字段中发现 quotechar,则引发Error
。
-
Dialect.
escapechar
¶ 如果 quoting 设置为
QUOTE_NONE
,作者使用一个字符串来转义 delimiter,如果 doublequote 是False
,则使用 quotechar。阅读时,escapechar 会删除以下字符中的任何特殊含义。它默认为None
,它禁用转义。
-
Dialect.
lineterminator
¶ 用于终止由
writer
生成的行的字符串。它默认为'\r\n'
。注解
reader
是硬编码的,以识别'\r'
或'\n'
作为行尾,并忽略 lineterminator。此行为可能会在将来更改。
-
Dialect.
quotechar
¶ 用于引用包含特殊字符(例如 delimiter 或 quotechar)或包含新行字符的字段的单字符字符串。它默认为
'"'
。
-
Dialect.
quoting
¶ 控制报价应由作者生成并由读者识别。它可以接受任何
QUOTE_*
常量(参见 模块内容 部分),默认为QUOTE_MINIMAL
。
14.1.3. 阅读器对象¶
Reader对象(DictReader
实例和 reader()
函数返回的对象)具有以下公共方法:
-
csvreader.
__next__
()¶ 返回读者的可迭代对象的下一行作为列表,根据当前方言解析。通常你应该把它叫做
next(reader)
。
Reader对象具有以下公共属性:
-
csvreader.
dialect
¶ 解析器使用的方言的只读描述。
-
csvreader.
line_num
¶ 从源迭代器读取的行数。这与返回的记录数不同,因为记录可以跨越多行。
DictReader对象具有以下公共属性:
-
csvreader.
fieldnames
¶ 如果在创建对象时未作为参数传递,则在首次访问时或从文件读取第一个记录时初始化此属性。
14.1.4. 作者对象¶
Writer
对象(DictWriter
实例和 writer()
函数返回的对象)具有以下公共方法。 row 必须是 Writer
对象的字符串或数字的可迭代字符串,以及将字符串映射到 DictWriter
对象的字符串或字符串(通过将它们传递通过 str()
)。注意,复数用柔义包围。这可能会导致一些问题,其他程序读取CSV文件(假设他们支持复数)。
-
csvwriter.
writerow
(row)¶ 将 row 参数写入写入程序的文件对象,根据当前方言格式化。
在 3.5 版更改: 增加了对任意迭代的支持。
-
csvwriter.
writerows
(rows)¶ 将所有 rows 参数(如上所述的 row 对象的列表)写入到作者的文件对象,根据当前方言格式化。
Writer对象具有以下公共属性:
-
csvwriter.
dialect
¶ 作者使用的方言的只读描述。
DictWriter对象具有以下公共方法:
-
DictWriter.
writeheader
()¶ 用字段名写入一行(在构造函数中指定)。
3.2 新版功能.
14.1.5. 例子¶
读取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文件,因此默认情况下该文件将使用系统默认编码(请参阅 locale.getpreferredencoding()
)解码为unicode。要使用不同的编码对文件进行解码,请使用open的 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) 如果未指定 |