14.1. csv
- CSV文件读取和写入¶
源代码: Lib / csv.py
所谓的CSV(Comma Separated Values)格式是电子表格和数据库最常见的导入和导出格式。在尝试以 RFC 4180以标准化方式描述格式之前,CSV格式已使用多年。The lack of a well-defined standard means that subtle differences often exist in the data produced and consumed by different applications.这些差异可能会让处理来自多个来源的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. Module Contents¶
csv
模块定义以下函数:
-
csv.
reader
(csvfile, dialect='excel', **fmtparams)¶ 返回一个读取器对象,它将在给定的csvfile中迭代。csvfile可以是任何支持iterator协议的对象,并且每次调用
__next__()
方法时返回一个字符串 - file objects和列表对象都是合适的。如果csvfile是文件对象,则应使用newline=''
打开它。[1]可以给出一个可选的方言参数,用于定义特定于某个CSV方言的一组参数。它可以是Dialect
类的子类的实例或list_dialects()
函数返回的字符串之一。可以给出其他可选的fmtparams关键字参数以覆盖当前方言中的各个格式化参数。有关方言和格式化参数的完整详细信息,请参见Dialects and Formatting Parameters一节。从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]打开。可以给出可选的方言参数,用于定义特定于特定CSV方言的一组参数。它可以是Dialect
类的子类的实例或list_dialects()
函数返回的字符串之一。可以给出其他可选的fmtparams关键字参数以覆盖当前方言中的各个格式化参数。有关方言和格式化参数的完整详细信息,请参见Dialects and Formatting Parameters一节。为了尽可能容易地与实现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
的子类或fmtparams关键字参数或两者来指定,其中关键字参数覆盖方言的参数。有关方言和格式化参数的完整详细信息,请参见Dialects and Formatting Parameters一节。
-
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)¶ 创建一个对象,其操作类似于普通读取器,但将读取的信息映射到一个dict中,其中的键由可选的fieldnames参数给出。fieldnames参数是一个
sequence
,其元素按顺序与输入数据的字段相关联。这些元素成为结果字典的键。如果省略fieldnames参数,则csvfile的第一行中的值将用作字段名称。如果读取的行具有比字段名序列更多的字段,则剩余数据将作为键值为restkey的序列添加。如果读取的行具有比字段名序列少的字段,则剩余的键使用可选的restval参数的值。任何其他可选或关键字参数都传递给底层的reader
实例。简短用法示例:
>>> 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
- 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中的新功能。
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
对象从不引用字段。当输出数据中出现当前定界符时,其前面为当前escapechar字符。如果未设置escapechar,如果遇到需要转义的字符,则写入程序将引发Error
。指示
reader
不对引号字符执行特殊处理。
csv
模块定义了以下异常:
- exception
csv.
Error
¶ 检测到错误时由任何函数引发。
14.1.2. Dialects and Formatting Parameters¶
为了更容易指定输入和输出记录的格式,特定的格式化参数被分组到方言中。方言是具有一组特定方法和单个validate()
方法的Dialect
类的子类。当创建reader
或writer
对象时,程序员可以指定Dialect
类的字符串或子类作为方言参数。In addition to, or instead of, the dialect parameter, the programmer can also specify individual formatting parameters, which have the same names as the attributes defined below for the Dialect
class.
方言支持以下属性:
-
Dialect.
delimiter
¶ 用于分隔字段的单字符字符串。它默认为
','
。
-
Dialect.
doublequote
¶ 控制在字段中出现的quotechar实例本身应如何引用。当
True
时,字符加倍。当False
时,escapechar用作quotechar的前缀。默认为True
。On output, if doublequote is
False
and no escapechar is set,Error
is raised if a quotechar is found in a field.
-
Dialect.
escapechar
¶ 写入器将分隔符(如果引用)转义的一个字符串设置为
QUOTE_NONE
和quotechar如果doublequote是False
。读取时,escapechar会删除以下字符中的任何特殊含义。它默认为None
,它禁用转义。
-
Dialect.
lineterminator
¶ 用于终止由
writer
生成的行的字符串。它默认为'\r\n'
。注意
reader
是硬编码的,以识别'\r'
或'\n'
作为行尾,并忽略 lineterminator。此行为可能会在将来更改。
-
Dialect.
quotechar
¶ 用于引用包含特殊字符(例如分隔符或quotechar)或包含换行字符的字段的单字符字符串。它默认为
'"'
。
-
Dialect.
quoting
¶ 控制何时报价应由作者生成并由读者识别。它可以接受任何
QUOTE_*
常量(参见Module Contents一节),默认为QUOTE_MINIMAL
。
14.1.3. Reader Objects¶
Reader对象(DictReader
实例和由reader()
函数返回的对象)有以下公共方法:
-
csvreader.
__next__
()¶ 返回读者的可迭代对象的下一行作为列表,根据当前方言解析。通常你应该把它叫做
next(reader)
。
Reader对象具有以下公共属性:
-
csvreader.
dialect
¶ 解析器使用的方言的只读描述。
-
csvreader.
line_num
¶ 从源迭代器读取的行数。这与返回的记录数不同,因为记录可以跨越多行。
DictReader对象具有以下公共属性:
-
csvreader.
fieldnames
¶
14.1.4. Writer Objects¶
Writer
对象(DictWriter
实例和由writer()
函数返回的对象)具有以下公共方法。A row must be an iterable of strings or numbers for Writer
objects and a dictionary mapping fieldnames to strings or numbers (by passing them through str()
first) for DictWriter
objects. 注意,复数用柔义包围。这可能会导致一些问题,其他程序读取CSV文件(假设他们支持复数)。
-
csvwriter.
writerow
(row)¶ 将行参数写入写入程序的文件对象,根据当前方言格式化。
在版本3.5中已更改:添加了对任意iterable的支持。
-
csvwriter.
writerows
(rows)¶ 将所有行参数(如上所述的行对象的列表)写入作者的文件对象,根据当前方言格式化。
Writer对象具有以下公共属性:
-
csvwriter.
dialect
¶ 作者使用的方言的只读描述。
DictWriter对象具有以下公共方法:
-
DictWriter.
writeheader
()¶ 用字段名写入一行(在构造函数中指定)。
版本3.2中的新功能。
14.1.5. Examples¶
读取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()
) 。要使用不同的编码对文件进行解码,请使用open的encoding
参数:
import csv
with open('some.csv', newline='', encoding='utf-8') as f:
reader = csv.reader(f)
for row in reader:
print(row)
这同样适用于在除系统默认编码以外的其他内容中写入:在打开输出文件时指定encoding参数。
注册新方言:
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 linendings写入额外\r 的平台上将被添加。指定newline='' 应该是安全的,因为csv模块有自己的(universal)换行处理。 |