Python与CSV文件(CSV模块)
1、CSV文件
CSV(逗号分隔值)格式是电子表格和数据库最常用的导入和导出格式。没有“CSV标准”,因此格式由许多读写的应用程序在操作上定义。缺乏标准意味着不同应用程序生成和使用的数据中通常存在细微差别。这些差异会使处理来自多个源的CSV文件变得很烦人。尽管如此,虽然分隔符和引用字符各不相同,但总体格式足够相似,以至于可以编写单个模块,该模块可以有效地操纵这些数据,隐藏从程序员读取和写入数据的细节。
2、csv---读【csv.
reader
(csvfile,dialect ='excel',** fmtparams )】
返回一个reader对象,它将迭代给定csvfile中的行。 csvfile可以是任何支持迭代器协议的对象,并在每次next()
调用其方法时返回一个字符串- 文件对象和列表对象都是合适的。如果csvfile是一个文件对象,那么它必须在平台上以“b”标志打开,这会产生影响。可以给出可选的 dialect 参数,该参数用于定义特定于CSV方言的一组参数。它可以是类的子类的实例,也可以是函数Dialect
返回的字符串之一 list_dialects()
。其他可选的fmtparams可以给出关键字参数来覆盖当前方言中的各个格式参数。
import csv
with open('erroe.csv','rb') as csvred:
spam = csv.reader(csvred,delimiter=' ', quotechar='|')
for rem in spam:
print ','.join(rem)
# date,time,env,qid,source,err_type
3、csv---写【csv.
writer
(csvfile,dialect ='excel',** fmtparams )】
返回一个编写器对象,负责将用户的数据转换为给定的类文件对象上的分隔字符串。 csvfile可以是带有write()
方法的任何对象 。如果csvfile是一个文件对象,那么它必须在平台上以“b”标志打开,这会产生影响。 可以给出可选的dialect参数,该参数用于定义特定于CSV方言的一组参数。它可以是类的子类的实例,也可以是函数Dialect
返回的字符串之一 list_dialects()
。可以给出其他可选的fmtparams关键字参数来覆盖当前dialect中的各个格式参数。
import csv
with open('error.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'])
# Spam Spam Spam Spam Spam |Baked Beans|
# Spam |Lovely Spam| |Wonderful Spam|
4、其它
4.1、csv.
register_dialect
(name,[ dialect,] ** fmtparams )
将dialect与name联系起来。 name必须是字符串或Unicode对象。dialect可以通过传递子类Dialect
,或通过fmtparams关键字参数或两者来指定,并使用关键字参数覆盖dialect的参数
4.2、 csv.
unregister_dialect
(name)
从dialect注册表中删除与名称关联的dialect。如果name不是已注册的dialect名称,则引发An 错误
4.3、csv.
get_dialect
(name)
返回与name相关的dialect。如果name 不是已注册的dialect名称,则引发An 错误
4.4、csv.
list_dialects
()
返回所有已注册dialect的名称
4.5、csv.
field_size_limit
([ new_limit ] )
返回解析器允许的当前最大字段大小。如果给出new_limit,则这将成为新限制
5、CSV模块定义的类
5.1、class csv.
DictReader
(f,fieldnames = None,restkey = None,restval = None,dialect ='excel',* args,** kwds )
创建一个像常规阅读器一样操作的对象,但将读取的信息映射到一个dict,其键由可选的 fieldnames参数给出。字段名的参数是一个序列,其元素与输入数据的顺序中的字段相关联。这些元素成为结果字典的关键。如果省略fieldnames参数,则文件f的第一行中的值将用作字段名。如果读取的行包含的字段多于字段名序列,则将剩余数据添加为由restkey值键入的序列。如果读取的行的字段数少于字段名序列,则其余的键将采用可选的restval参数的值。任何其他可选或关键字参数都将传递给基础reader
实例。
import csv
with open('/Users/mioji/Desktop/api_error/error.csv') as csvfile:
reader = csv.DictReader(csvfile)
for row in reader:
print(row['apan'], row['spam'])
# Baked Beans
# Lovely Spam
# Wonderful Spam
5.2、class csv.
DictWriter
(f,fieldnames,restval ='',extrasaction ='raise',dialect ='excel',* args,** kwds )
创建一个像常规编写器一样操作的对象,但将字典映射到输出行。的字段名的参数是一个序列识别在哪些值在传递给字典中的顺序按键的writerow()
方法被写入到文件˚F。如果字典缺少字段名中的键,则可选的restval参数指定要写入的值。如果传递给方法的字典包含在字段名中找不到的键,则可选的extrasaction参数指示要采取的操作。如果设置为a 则被提升。如果设置为writerow()
'raise'
ValueError
'ignore'
,字典中的额外值将被忽略。任何其他可选或关键字参数都将传递给基础 writer
实例。
请注意,与DictReader
类不同,它的fieldnames参数DictWriter
不是可选的。由于Python的dict
对象没有排序,因此没有足够的信息来推断应该将行写入文件f的顺序。
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'})
5.3、class csv.
Dialect
-
Dialect
类是依赖于主要用于它的属性,这是用来定义一个特定的参数的容器类reader
或writer
实例
5.4、class csv.
excel
-
在
excel
类定义的Excel生成CSV文件的通常的性质。它以方言名称注册'excel'
。
5.5、class csv.
excel_tab
-
excel_tab
类定义Excel生成的制表符分隔的文件的通常的性质。它以方言名称注册'excel-tab'
。
5.6、class csv.
Sniffer
-
Sniffer
类用来推断一个CSV文件的格式。Sniffer
类提供了两个方法:-
sniff
(样本,分隔符=无) -
分析给定的样本并返回
Dialect
反映找到的参数的子类。如果给出了可选的delimiters参数,则将其解释为包含可能的有效分隔符的字符串。
-
has_header
(样本) -
分析示例文本(假定为CSV格式),
True
如果第一行看起来是一系列列标题,则返回。
-
6、CSV模块定义以下常量
6.1、csv.
QUOTE_ALL
-
指示
writer
对象引用所有字段。
6.2、csv.
QUOTE_MINIMAL
-
指示
writer
对象只引用那些包含特殊字符,如字段分隔符,quotechar或任何字符 lineterminator。
6.3、csv.
QUOTE_NONNUMERIC
-
指示
writer
对象引用所有非数字字段。指示读者将所有非引用字段转换为float类型。
6.4、csv.
QUOTE_NONE
-
指示
writer
对象永远不引用字段。当输出数据中出现当前 分隔符时,它前面是当前的escapechar 字符。如果未设置escapechar,则Error
在遇到需要转义的任何字符时,编写器将引发。指示
reader
不对引号字符执行特殊处理。
6.5、csv
模块定义了以下异常:
-
异常
csv.
Error
-
检测到错误时由任何功能引发
7、Dialects and Formatting 参数
为了更容易指定输入和输出记录的格式,将特定格式参数组合在一起成为Dialects。Dialects是Dialect
具有一组特定方法和单个validate()
方法的类的子类。在创建reader
或writer
对象时,可以指定类的字符串或子Dialect
类作为dialect参数。除了Dialects参数之外,或者代替Dialects参数,还可以指定单独的格式化参数,这些参数与下面为Dialect
类定义的属性具有相同的名称。
7.1、Dialects支持以下属性:
7.1.1、Dialect.
delimiter
-
','
。
7.1.2、Dialect.
doublequote
-
True
,角色加倍。当False
时,escapechar作为前缀quotechar。它默认为True
。 - 在输出时,如果双引号是
False
没有escapechar设置,Error
如果需要进行上调quotechar是在现场发现的。
7.1.3、Dialect.
escapechar
-
QUOTE_NONE
与quotechar如果双引号是False
。在阅读时,escapechar从以下字符中删除任何特殊含义。它默认为None
,禁用转义。
7.1.4、Dialect.
lineterminator
-
writer
。它默认为'\r\n'
。 - PS:
-
它
reader
是硬编码的,用于识别'\r'
或者'\n'
作为行尾,并忽略行终止符。此行为将来可能会发生变化。
7.1.5、Dialect.
quotechar
-
一个单字符的字符串,用于引用包含特殊字符的字段,例如分隔符或quotechar,或者包含换行符。它默认为
'"'
。
7.1.6、Dialect.
quoting
-
QUOTE_*
常量,默认为QUOTE_MINIMAL
。
7.1.7、Dialect.
skipinitialspace
何时True
,忽略分隔符后面的空格。默认是False
。
7.1.8、Dialect.
strict
-
True
,Error
在错误的CSV输入上引发异常。默认是False
。
8、Reader对象
Reader对象(函数DictReader
返回的实例和对象 reader()
)具有以下公共方法:
-
csvreader.
next
() - 将读者的可迭代对象的下一行作为列表返回,根据当前方言进行解析。
Reader对象具有以下公共属性:
csvreader.
dialect
解析器使用的方言的只读描述。
-
csvreader.
line_num
-
- 2.5版中的新功能。
- DictReader对象具有以下公共属性:
-
csvreader.
fieldnames
-
9、Writer
对象
-
Writer
对象(函数DictWriter
返回的实例和对象writer()
)具有以下公共方法。甲行必须是字符串或数字为序列Writer
对象和一个字典映射字段名到字符串或数字(通过使它们通过str()
第一)为DictWriter
对象。请注意,复数会被parens包围。这可能会导致其他读取CSV文件的程序出现问题(假设它们支持复数)。
-
csvwriter.
writerow
(行) - 将row参数写入writer的文件对象,根据当前方言进行格式化。
-
csvwriter.
writerows
(行) - 将行中的所有元素(如上所述的可迭代行对象)写入编写器的文件对象,并根据当前Dialects进行格式化。
- Writer对象具有以下public属性:
-
csvwriter.
dialect
-
Writer
使用的Dialects的只读描述。 - DictWriter对象具有以下公共方法:
-
DictWriter.
writeheader
() - 使用字段名称(在构造函数中指定)写一行。
10、使用
读取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)
注册新Dialects:
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,但除了ASCII NUL字符的一些问题外,它还是8位清除。因此,只要您避免使用像UTF-16这样使用NUL的编码,您就可以编写处理编码和解码的函数或类。建议使用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)