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 改善建议书 提出了对Python的添加。
14.1.1. 模块内容¶
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. 方言和格式参数¶
为了更容易指定输入和输出记录的格式,特定的格式化参数被分组到方言中。方言是具有一组特定方法和单个validate()
方法的Dialect
类的子类。当创建reader
或writer
对象时,程序员可以指定Dialect
类的字符串或子类作为方言参数。除了dialect参数外,程序员还可以指定单独的格式参数,它们与Dialect
类的下面定义的属性具有相同的名称。
方言支持以下属性:
-
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应由writer生成并由reader识别。它可以接受任何
QUOTE_*
常量(参见Module Contents一节),默认为QUOTE_MINIMAL
。
14.1.3. Reader 对象¶
Reader对象(DictReader
实例和由reader()
函数返回的对象)有以下公共方法:
-
csvreader.
__next__
()¶ 返回Reader的可迭代对象的下一行作为列表,根据当前方言解析。通常你应该把它叫做
next(reader)
。
Reader对象具有以下公共属性:
-
csvreader.
dialect
¶ 解析器使用的方言的只读描述。
-
csvreader.
line_num
¶ 从源迭代器读取的行数。这与返回的记录数不同,因为记录可以跨越多行。
DictReader对象具有以下公共属性:
-
csvreader.
fieldnames
¶
14.1.4. Writer 对象¶
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)¶ 将参数row写入写入器的文件对象,根据当前方言格式化。
在版本3.5中已更改:添加了对任意iterable的支持。
-
csvwriter.
writerows
(rows)¶ 将所有行参数(如上所述的行对象的列表)写入writer的文件对象,根据当前方言格式化。
Writer对象具有以下公共属性:
-
csvwriter.
dialect
¶ Writer使用的方言的只读描述。
DictWriter对象具有以下公共方法:
-
DictWriter.
writeheader
()¶ 用字段名写入一行(在构造函数中指定)。
版本3.2中的新功能。
14.1.5. 实例¶ T0>
读取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)换行处理。 |