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)