CSV文件读写(1)Python文件格式(必读进阶Python教程)(参考资料)
所谓的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的这一补充。
模块内容
该csv
模块定义了以下功能:
csv.
reader
(csvfile,dialect =’excel’,** fmtparams )- 返回一个读取器对象,它将迭代给定csvfile中的行。 csvfile可以是任何支持迭代器协议的对象,并在每次
__next__()
调用其方法时返回一个字符串- 文件对象和列表对象都是合适的。如果csvfile是文件对象,则应该打开它newline=''
。[1]可以给出 一个可选的 方言参数,用于定义特定于CSV方言的一组参数。它可以是类的子类的实例,也可以是函数Dialect
返回的字符串之一list_dialects()
。其他可选的fmtparams可以给出关键字参数来覆盖当前方言中的各个格式参数。有关方言和格式参数的完整详细信息,请参阅方言和格式参数一节。从csv文件读取的每一行都作为字符串列表返回。除非
QUOTE_NONNUMERIC
指定了format选项(在这种情况下,未加引号的字段将转换为浮点数),否则不会执行自动数据类型转换。一个简短的用法示例:
>>> >>> 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关键字参数来覆盖当前方言中的各个格式参数。有关方言和格式参数的完整详细信息,请参阅部分方言和格式参数。为了使与实现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 ] ] )- 将方言与名称联系起来。 name必须是一个字符串。方言可以通过传递子类
Dialect
,或通过fmtparams关键字参数或两者来指定,并使用关键字参数覆盖方言的参数。有关方言和格式参数的完整详细信息,请参阅方言和格式参数一节。
csv.
unregister_dialect
(名字)- 从方言注册表中删除与名称关联的方言。
Error
如果name不是已注册的方言名称,则引发An 。
csv.
get_dialect
(名字)- 返回与姓名相关的方言。
Error
如果name不是已注册的方言名称,则引发 An 。此函数返回不可变的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 ) - 创建一个像常规阅读器一样操作的对象,但将每行中的信息映射到
OrderedDict
其键由可选的fieldnames参数给出。的字段名的参数是一个序列。如果省略fieldnames,则文件f的第一行中的值将用作字段名。无论字段名如何确定,有序字典都保留其原始顺序。
如果一行包含的字段多于字段名,则将剩余数据放入一个列表中,并使用restkey指定的字段名(默认为
None
)进行存储。如果非空行的字段少于字段名,则缺少的值将填入None
。所有其他可选或关键字参数都传递给基础
reader
实例。在版本3.6中更改:返回的行现在是类型
OrderedDict
。一个简短的用法示例:
>>> >>> 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) OrderedDict([('first_name', 'John'), ('last_name', 'Cleese')])
- class
csv.
DictWriter
(f,fieldnames,restval =”,extrasaction =’raise’,dialect =’excel’,* args,** kwds ) - 创建一个像常规编写器一样操作的对象,但将字典映射到输出行。的字段名的参数是一个
sequence
标识,其中在传递给字典值的顺序按键的writerow()
方法被写入到文件 ˚F。如果字典缺少字段名中的键,则可选的restval参数指定要写入的值。如果传递给方法的字典包含在字段名中找不到的键 ,则可选的extrasaction参数指示要采取的操作。如果设置为, 则引发默认值a 。如果设置为writerow()
'raise'
ValueError
'ignore'
,字典中的额外值将被忽略。任何其他可选或关键字参数都将传递给基础writer
实例。请注意,与
DictReader
类不同,类的fieldnames参数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'})
- 类
csv.
Dialect
- 的
Dialect
类是依赖于主要用于它的属性,这是用来定义一个特定的参数的容器类reader
或writer
实例。
- 类
csv.
excel
- 在
excel
类定义的Excel生成CSV文件的通常的性质。它以方言名称注册'excel'
。
- 类
csv.
excel_tab
- 所述
excel_tab
类定义Excel生成的制表符分隔的文件的通常的性质。它以方言名称注册'excel-tab'
。
- 类
csv.
unix_dialect
- 的
unix_dialect
类定义在UNIX系统上,即,使用生成的CSV文件的通常性质'\n'
如线路终端机和引用的所有字段。它以方言名称注册'unix'
。版本3.2中的新功能。
- 类
csv.
Sniffer
- 本
Sniffer
类用来推断一个CSV文件的格式。本
Sniffer
类提供了两个方法:sniff
(样本,分隔符=无)- 分析给定的样本并返回
Dialect
反映找到的参数的子类。如果给出了可选的delimiters参数,则将其解释为包含可能的有效分隔符的字符串。
has_header
(样本)- 分析示例文本(假定为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
对象只引用那些包含特殊字符,如字段分隔符,quotechar或任何字符 lineterminator。
csv.
QUOTE_NONNUMERIC
- 指示
writer
对象引用所有非数字字段。指示读者将所有非引用字段转换为float类型。
csv.
QUOTE_NONE
- 指示
writer
对象永远不引用字段。当输出数据中出现当前 分隔符时,它前面是当前的escapechar 字符。如果未设置escapechar,则Error
在遇到任何需要转义的字符时,编写器将引发。指示
reader
不对引号字符执行任何特殊处理。
该csv
模块定义了以下异常:
- 异常
csv.
Error
- 检测到错误时由任何功能引发。
方言和格式参数
为了便于指定输入和输出记录的格式,将特定格式参数组合在一起成为方言。方言是Dialect
具有一组特定方法和单个validate()
方法的类的子类。在创建reader
或 writer
对象时,程序员可以指定类的字符串或子Dialect
类作为dialect参数。除了方言参数之外,或者代替方言参数,程序员还可以指定单独的格式化参数,这些参数与下面为Dialect
类定义的属性具有相同的名称。
方言支持以下属性:
Dialect.
delimiter
- 用于分隔字段的单字符字符串。它默认为
','
。
Dialect.
doublequote
- 控制如何引用字段中出现的quotechar实例。什么时候
True
,角色加倍。当False
时,escapechar作为前缀quotechar。它默认为True
。在输出时,如果双引号是
False
没有escapechar设置,Error
如果需要进行上调quotechar是在现场发现的。
Dialect.
escapechar
- 由作家使用的一个字符串转换为逃避分隔符,如果报价 被设置为
QUOTE_NONE
与quotechar如果双引号是False
。在阅读时,escapechar从以下字符中删除任何特殊含义。默认为None
,禁用转义。
Dialect.
lineterminator
- 用于终止由生成的行的字符串
writer
。它默认为'\r\n'
。注意
它
reader
是硬编码的,可以识别'\r'
或者'\n'
作为行尾,并忽略行终止符。此行为将来可能会发生变化。
Dialect.
quotechar
- 一个单字符的字符串,用于引用包含特殊字符的字段,例如分隔符或quotechar,或者包含换行符。它默认为
'"'
。
Dialect.
quoting
- 控制何时应由作者生成引号并由读者识别。它可以采用任何
QUOTE_*
常量(请参阅模块内容一节 )并默认为QUOTE_MINIMAL
。
Dialect.
skipinitialspace
- 何时
True
,忽略分隔符后面的空格。默认是False
。
Dialect.
strict
- 何时
True
,Error
在错误的CSV输入上引发异常。默认是False
。
读者对象
Reader对象(函数DictReader
返回的实例和对象 reader()
)具有以下公共方法:
csvreader.
__next__
()- 将读者的可迭代对象的下一行作为列表(如果对象是从中返回
reader()
)或dict(如果它是DictReader
实例)返回,根据当前方言进行解析。通常你应该称之为next(reader)
。
Reader对象具有以下公共属性:
csvreader.
dialect
- 解析器使用的方言的只读描述。
csvreader.
line_num
- 从源迭代器读取的行数。这与返回的记录数不同,因为记录可以跨越多行。
DictReader对象具有以下公共属性:
csvreader.
fieldnames
- 如果在创建对象时未作为参数传递,则在首次访问时或从文件中读取第一条记录时初始化此属性。
csvwriter
对象
Writer
对象(函数DictWriter
返回的实例和对象writer()
)具有以下公共方法。甲行必须是可迭代字符串或数字用于Writer
对象和一个字典映射字段名到字符串或数字(通过使它们通过str()
第一)为DictWriter
对象。请注意,复数会被parens包围。这可能会导致其他读取CSV文件的程序出现问题(假设它们支持复数)。
csvwriter.
writerow
(行)- 将row参数写入writer的文件对象,根据当前方言进行格式化。
版本3.5中已更改:添加了对任意迭代的支持。
csvwriter.
writerows
(行)- 将行中的所有元素(如上所述的行对象的可迭代)写入编写器的文件对象,根据当前方言进行格式化。
Writer对象具有以下公共属性:
csvwriter.
dialect
- 作者使用的方言的只读描述。
DictWriter对象具有以下公共方法:
DictWriter.
writeheader
()- 使用字段名称(在构造函数中指定)写一行。
版本3.2中的新功能。
示例
读取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
open 的参数:
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模块执行其自己的(通用)换行处理。 |