csv
csv - CSV文件的读取和写入
2.3版本的新功能。
所谓的CSV(逗号分隔值)格式是电子表格和数据库最常用的导入和导出格式。没有“CSV标准”,所以格式是由读写它的许多应用程序在操作上定义的。缺乏标准意味着不同应用程序生成和使用的数据中经常存在细微差异。这些差异可能会令人讨厌从多个来源处理CSV文件。尽管分隔符和引用字符有所不同,但整体格式足够相似,可以编写一个可以高效处理这些数据的模块,从编程器中隐藏读取和写入数据的细节。
该csv
模块实现了以CSV格式读取和写入表格数据的类。它允许程序员说出“用Excel首选的格式写这些数据”,或者“从Excel生成的这个文件中读取数据”,而不知道Excel使用的CSV格式的确切细节。程序员还可以描述其他应用程序可以理解的CSV格式,或者定义他们自己的专用CSV格式。
该csv
模块reader
和writer
对象读取和写入序列。程序员也可以使用DictReader
和DictWriter
类以字典形式读写数据。
注意
该版本的csv
模块不支持Unicode输入。此外,目前有关于ASCII NUL字符的一些问题。因此,所有输入应该是UTF-8或可打印的ASCII,以确保安全; 请参阅示例部分中的示例。
另请参阅
PEP 305
- CSV文件API Python增强建议,它向Python提出了这个补充。
1.模块内容
csv
模块定义了以下功能:
csv.reader(csvfile, dialect='excel', **fmtparams)
返回将在给定的csv文件中
遍历行的reader对象。csvfile
可以是任何支持迭代器协议的对象,每次next()
调用它的方法时都会返回一个字符串- 文件对象和列表对象都适用。如果csvfile
是一个文件对象,那么它必须在平台上用“b”标志打开,这是有所作为的
。可以给出可选的方言
参数,该参数用于定义特定CSV方言
的一组参数。它可能是Dialect
该类的子类的实例或list_dialects()
函数返回的一个字符串。其他可选的fmtparams
可以给出关键字参数来覆盖当前方言
中的单个格式参数。有关方言
和格式参数的完整详细信息,请参见方言
和格式参数一节。
从csv文件读取的每一行都以字符串列表形式返回。不执行自动数据类型转换。
一个简短的用法示例:
>>> import csv
>>> with open('eggs.csv', 'rb') 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
在版本2.5中进行了更改:对于多行引用字段,解析器现在更严格。以前,如果一行中没有终止换行符的引用字段结束,换行符会插入到返回的字段中。当读取字段中包含回车符的文件时,此行为会导致问题。该行为已更改为在不插入换行符的情况下返回该字段。因此,如果字段中嵌入的换行符非常重要,则输入应以保留换行符的方式拆分为行。
csv.writer(csvfile, dialect='excel', **fmtparams)
返回一个编写器对象,负责将用户的数据转换为给定类文件对象上的分隔字符串。csvfile
可以是具有write()
方法的任何对象。如果csvfile
是一个文件对象,那么它必须在平台上用“b”标志打开,这是有所作为的
。可以给出可选的方言
参数,该参数用于定义特定CSV方言
的一组参数。它可能是Dialect
该类的子类的实例或list_dialects()
函数返回的一个字符串。其他可选的fmtparams
可以给出关键字参数来覆盖当前方言
中的单个格式参数。有关方言
和格式参数的完整详细信息,请参见方言
和格式参数一节。为了尽可能简化与实现DB API的模块的接口,该值None
被写为空字符串。虽然这不是可逆的转换,但它可以更轻松地将SQL NULL数据值转储到CSV文件,而无需预处理从cursor.fetch*
调用返回的数据。repr()
在写入之前,浮动字符串会被字符串化。所有其他非字符串数据str()
在写入之前都会被字符串化。
一个简短的用法示例:
import csv
with open('eggs.csv', 'wb') 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)
将方言
与名字联系起来
。名称
必须是字符串或Unicode对象。方言
可以通过传递子类Dialect
或fmtparams
关键字参数或两者来指定,其中关键字参数覆盖方言
的参数。有关方言
和格式参数的完整详细信息,请参见方言
和格式参数一节。
csv.unregister_dialect(name)
从方言注册表中删除与姓名
关联的方言。Error
如果名称
不是已注册的方言名称
,则引发An 。
csv.get_dialect(name)
返回与名称
关联的方言。如果名称
不是已注册的方言名称
,则引发Error
。
在版本2.5中更改:此函数现在返回一个不可变的Dialect
。以前,所请求方言的一个实例已被返回。用户可以修改底层的类,改变活跃的读者和作者的行为。
csv.list_dialects()
返回所有注册方言的名称。
csv.field_size_limit([new_limit])
返回解析器允许的当前最大字段大小。如果给出new_limit
,则这成为新的限制。
2.5版本中的新功能。
该csv
模块定义了以下类:
class csv.DictReader(csvfile, fieldnames=None, restkey=None, restval=None, dialect='excel', *args, **kwds)
创建一个像普通阅读器一样运行的对象,但将读取的信息映射到由可选fieldnames
参数提供的键的字典中。的字段名
的参数是,其元件与所述输入数据的顺序中的字段相关联的序列。这些元素成为最终字典的关键。如果省略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)
创建一个像普通作家一样操作的对象,但将字典映射到输出行。该字段名
参数是标识在其中在传递给字典值的顺序键的序列writerow()
的方法被写入到csvfile
。可选的restval
参数指定字典在字段名
称中缺少键时要写入的值。如果传递给writerow()
方法的字典包含在字段名中
找不到的键,则可选的extrasaction
参数指示要执行的操作。如果它被设置为'raise'
一个ValueError
提高。如果它设置为'ignore'
,字典中的额外值将被忽略。任何其他可选参数或关键字参数都会传递给底层writer
实例。
请注意,与DictReader
类不同,该字段的fieldnames
参数DictWriter
不是可选的。由于Python的dict
对象没有排序,因此没有足够的信息来推断行应该写入csv
文件的顺序
。
一个简短的用法示例:
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.Dialect
Dialect
类是依赖于主要用于它的属性,这是用来定义一个特定的参数的容器类reader
或writer
实例。
class csv.excel
在excel
类定义的Excel生成CSV文件的通常的性质。它用方言名称注册'excel'
。
class csv.excel_tab
所述excel_tab
类定义Excel生成的制表符分隔的文件的通常的性质。它用方言名称注册'excel-tab'
。
class csv.Sniffer
本Sniffer
类用来推断一个CSV文件的格式。
本Sniffer
类提供了两个方法:
sniff(sample, delimiters=None)
分析给定的样本
并返回Dialect
反映所发现参数的子类。如果给出了可选的delimiters
参数,则将其解释为包含可能的有效分隔符字符的字符串。
has_header(sample)
分析示例文本(推测为CSV格式),并True
在第一行显示为一系列列标题时返回。
使用示例Sniffer
:
with open('example.csv', 'rb') 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
模块定义了以下例外情况:
exception csv.Error
当检测到错误时由任何功能引发。
2.方言和格式参数
为了更容易指定输入和输出记录的格式,特定的格式参数被组合为方言
。方言
是Dialect
具有一组特定方法和单一validate()
方法的类的子类。在创建reader
或writer
对象时,程序员可以将该类的字符串或子类指定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'
作为行结束,并忽略lineterminator
。这种行为在未来可能会改变。
Dialect.quotechar
一个字符的字符串,用于引用包含特殊字符(如分隔符
或引号
)或包含换行符的
字段。它默认为'"'
。
Dialect.quoting
控制引号应由作者生成并由读者识别。它可以采用任何QUOTE_*
常量(请参见模块内容部分),并且默认为QUOTE_MINIMAL
。
Dialect.skipinitialspace
当True
,忽略分隔符
后面的空格。默认是False
。
Dialect.strict
什么时候出现错误的CSV输入True
异常Error
。默认是False
。
3.阅读器对象
Reader对象(函数DictReader
返回的实例和对象reader()
)具有以下公用方法:
csvreader.next()
将读者的可迭代对象的下一行作为列表返回,根据当前的方言进行解析。
读者对象具有以下公共属性:
csvreader.dialect
解析器使用的方言的只读描述。
csvreader.line_num
从源迭代器读取的行数。这与返回的记录数量不同,因为记录可以跨越多行。
2.5版本中的新功能。
DictReader对象具有以下公共属性:
csvreader.fieldnames
如果在创建对象时未作为参数传递,则在首次访问或从文件读取第一条记录时初始化此属性。
在版本2.6中更改。
4.作家对象
Writer
对象(DictWriter
由writer()
函数返回的实例和对象)具有以下公共方法。甲行
必须是字符串或数字为序列Writer
对象和一个字典映射字段名到字符串或数字(通过使它们通过str()
第一)为DictWriter
对象。请注意,复数数字是由parens包围的。这可能会导致读取CSV文件的其他程序出现问题(假设它们完全支持复数)。
csvwriter.writerow(row)
将行
参数写入作者的文件对象,根据当前的方言格式化。
csvwriter.writerows(rows)
将所有行
参数(如上所述的行
对象列表)写入作者的文件对象,根据当前的方言格式化。
编写器对象具有以下公共属性:
csvwriter.dialect
作者正在使用的方言的只读说明。
DictWriter对象具有以下公用方法:
DictWriter.writeheader()
用字段名写一行(如构造函数中指定的那样)。
2.7版本的新功能。
5.例子
读取CSV文件的最简单示例:
import csv
with open('some.csv', 'rb') as f:
reader = csv.reader(f)
for row in reader:
print row
用另一种格式读取文件:
import csv
with open('passwd', 'rb') as f:
reader = csv.reader(f, delimiter=':', quoting=csv.QUOTE_NONE)
for row in reader:
print row
相应的最简单的写作示例是:
import csv
with open('some.csv', 'wb') as f:
writer = csv.writer(f)
writer.writerows(someiterable)
注册一种新的方言:
import csv
csv.register_dialect('unixpwd', delimiter=':', quoting=csv.QUOTE_NONE)
with open('passwd', 'rb') as f:
reader = csv.reader(f, 'unixpwd')
稍微更高级的读者使用 - 捕捉和报告错误:
import csv, sys
filename = 'some.csv'
with open(filename, 'rb') as f:
reader = csv.reader(f)
try:
for row in reader:
print row
except csv.Error as e:
sys.exit('file %s, line %d: %s' % (filename, reader.line_num, e))
虽然模块不直接支持分析字符串,但可以轻松完成:
import csv
for row in csv.reader(['one,two,three']):
print row
该csv
模块不直接支持读取和写入Unicode,但它是8位清除的,用于存储ASCII NUL字符的一些问题。因此,只要避免使用NUL的UTF-16编码,就可以编写处理编码和解码的函数或类。建议使用UTF-8。
unicode_csv_reader()
下面是一个生成器,csv.reader
用于处理Unicode CSV数据(Unicode字符串列表)。utf_8_encoder()
是一个发电机编码的Unicode字符串为UTF-8,一个字符串(或行)一次。编码的字符串由CSV阅读器解析,并将unicode_csv_reader()
UTF-8编码的单元解码为Unicode:
import csv
def unicode_csv_reader(unicode_csv_data, dialect=csv.excel, **kwargs):
# csv.py doesn't do Unicode; encode temporarily as UTF-8:
csv_reader = csv.reader(utf_8_encoder(unicode_csv_data),
dialect=dialect, **kwargs)
for row in csv_reader:
# decode UTF-8 back to Unicode, cell by cell:
yield [unicode(cell, 'utf-8') for cell in row]
def utf_8_encoder(unicode_csv_data):
for line in unicode_csv_data:
yield line.encode('utf-8')
对于所有其他编码
,可以使用以下UnicodeReader
和UnicodeWriter
类。他们在构造函数中使用额外的编码
参数,并确保数据通过编码
为UTF-8的真实读写器:
import csv, codecs, cStringIO
class UTF8Recoder:
"""
Iterator that reads an encoded stream and reencodes the input to UTF-8
"""
def __init__(self, f, encoding):
self.reader = codecs.getreader(encoding)(f)
def __iter__(self):
return self
def next(self):
return self.reader.next().encode("utf-8")
class UnicodeReader:
"""
A CSV reader which will iterate over lines in the CSV file "f",
which is encoded in the given encoding.
"""
def __init__(self, f, dialect=csv.excel, encoding="utf-8", **kwds):
f = UTF8Recoder(f, encoding)
self.reader = csv.reader(f, dialect=dialect, **kwds)
def next(self):
row = self.reader.next()
return [unicode(s, "utf-8") for s in row]
def __iter__(self):
return self
class UnicodeWriter:
"""
A CSV writer which will write rows to CSV file "f",
which is encoded in the given encoding.
"""
def __init__(self, f, dialect=csv.excel, encoding="utf-8", **kwds):
# Redirect output to a queue
self.queue = cStringIO.StringIO()
self.writer = csv.writer(self.queue, dialect=dialect, **kwds)
self.stream = f
self.encoder = codecs.getincrementalencoder(encoding)()
def writerow(self, row):
self.writer.writerow([s.encode("utf-8") for s in row])
# Fetch UTF-8 output from the queue ...
data = self.queue.getvalue()
data = data.decode("utf-8")
# ... and reencode it into the target encoding
data = self.encoder.encode(data)
# write to the target stream
self.stream.write(data)
# empty queue
self.queue.truncate(0)
def writerows(self, rows):
for row in rows:
self.writerow(row)