Python与CSV文件(CSV模块)

Python与CSV文件(CSV模块)

 

1、CSV文件

  CSV(逗号分隔值)格式是电子表格和数据库最常用的导入和导出格式。没有“CSV标准”,因此格式由许多读写的应用程序在操作上定义。缺乏标准意味着不同应用程序生成和使用的数据中通常存在细微差别。这些差异会使处理来自多个源的CSV文件变得很烦人。尽管如此,虽然分隔符和引用字符各不相同,但总体格式足够相似,以至于可以编写单个模块,该模块可以有效地操纵这些数据,隐藏从程序员读取和写入数据的细节。

2、csv---读【csv.readercsvfiledialect ='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.writercsvfiledialect ='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_dialectnamedialect** fmtparams 

  将dialectname联系起来。 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_limitnew_limit 

  返回解析器允许的当前最大字段大小。如果给出new_limit,则这将成为新限制

5、CSV模块定义的类

5.1、class csv.DictReaderffieldnames = Nonerestkey = Nonerestval = Nonedialect ='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.DictWriterffieldnamesrestval =''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类是依赖于主要用于它的属性,这是用来定义一个特定的参数的容器类 readerwriter实例

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()方法的类的子类。在创建readerwriter对象时,可以指定类的字符串或子Dialect类作为dialect参数。除了Dialects参数之外,或者代替Dialects参数,还可以指定单独的格式化参数,这些参数与下面为Dialect类定义的属性具有相同的名称。

 7.1、Dialects支持以下属性:

7.1.1、Dialect.delimiter

  用于分隔字段的单字符字符串。它默认为','

7.1.2、Dialect.doublequote

  控制如何引用字段中出现的quotechar实例。什么时候True,角色加倍。当 False时,escapechar作为前缀quotechar。它默认为True
  在输出时,如果双引号False没有escapechar设置, Error如果需要进行上调quotechar是在现场发现的。

7.1.3、Dialect.escapechar

  使用的一个字符串转换为分隔符,如果delimiter 被设置为QUOTE_NONEquotechar如果双引号是 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

  何时TrueError在错误的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)
posted @ 2019-08-08 11:12  不夜男人  阅读(1765)  评论(0编辑  收藏  举报