csv --- CSV 文件讀寫?
源代碼: Lib/csv.py
CSV (Comma Separated Values) 格式是電子表格和數據庫中最常見的輸入、輸出文件格式。在 RFC 4180 規范推出的很多年前,CSV 格式就已經被開始使用了,由于當時并沒有合理的標準,不同應用程序讀寫的數據會存在細微的差別。這種差別讓處理多個來源的 CSV 文件變得困難。但盡管分隔符會變化,此類文件的大致格式是相似的,所以編寫一個單獨的模塊以高效處理此類數據,將程序員從讀寫數據的繁瑣細節中解放出來是有可能的。
The csv module implements classes to read and write tabular data in CSV
format. It allows programmers to say, "write this data in the format preferred
by Excel," or "read data from this file which was generated by Excel," without
knowing the precise details of the CSV format used by Excel. Programmers can
also describe the CSV formats understood by other applications or define their
own special-purpose CSV formats.
csv 模塊中的 reader?類和 writer 類可用于讀寫序列化的數據。也可使用 DictReader 類和 DictWriter?類以字典的形式讀寫數據。
參見
- 該實現在“Python 增強提議” - PEP 305 (CSV 文件 API) 中被提出
《Python 增強提議》提出了對 Python 的這一補充。
模塊內容?
csv 模塊定義了以下函數:
-
csv.reader(csvfile, dialect='excel', **fmtparams)? 返回一個 reader 對象,該對象將逐行遍歷 csvfile。csvfile 可以是任何對象,只要這個對象支持 iterator 協議并在每次調用
__next__()方法時都返回字符串,文件對象 和列表對象均適用。如果 csvfile 是文件對象,則打開它時應使用newline=''。 1 可選參數 dialect 是用于不同的 CSV 方言的特定參數組。它可以是Dialect類的子類的實例,也可以是list_dialects()函數返回的字符串之一。另一個可選關鍵字參數 fmtparams 可以覆寫當前方言格式中的單個格式設置。有關方言和格式設置參數的完整詳細信息,請參見 變種與格式參數 部分。csv 文件的每一行都讀取為一個由字符串組成的列表。除非指定了
QUOTE_NONNUMERIC格式選項(在這種情況下,未引用的字段會轉換為浮點數),否則不會執行自動數據類型轉換。一個簡短的用法示例:
>>> 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 可選參數 dialect 是用于不同的 CSV 方言的特定參數組。它可以是Dialect類的子類的實例,也可以是list_dialects()函數返回的字符串之一。另一個可選關鍵字參數 fmtparams 可以覆寫當前方言格式中的單個格式設置。有關方言和格式設置參數的完整詳細信息,請參見 變種與格式參數 部分。為了盡量簡化與數據庫 API 模塊之間的對接,None值會寫入為空字符串。雖然這個轉換是不可逆的,但它讓 SQL 空數據值轉儲到 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 關聯起來。name 必須是字符串。要指定變種 (dialect),可以給出
Dialect的子類,或給出 fmtparams 關鍵字參數,或兩者都給出,此時關鍵字參數會覆蓋 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)? 創建一個對象,其操作類似于常規 reader 但會將每行中的信息映射到一個
OrderedDict,其中的鍵由可選的 fieldnames 形參給出。fieldnames 形參是一個 sequence。 如果省略 fieldnames,則文件 f 第一行中的值將被用作字段名。 無論字段名是如何確定的,有序字典都將保留其原始順序。
如果某一行中的字段多于字段名,則剩余數據會被放入一個列表,并與 restkey 所指定的字段名 (默認為
None) 一起保存。 如果某個非空白行的字段少于字段名,則缺失的值會使用 restval 的值來填充 (默認為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)? 創建一個對象,該對象在操作上類似常規 writer,但能將字典映射到輸出行。fieldnames 參數是由 key(鍵)組成的
序列,用于指定字典中的 value (值)的順序,這些值會按指定順序傳遞給writerow()方法并寫入 f 文件。如果字典缺少 fieldnames 中的鍵,則可選參數 restval 用于指定要寫入的值。如果傳遞給writerow()方法的字典的某些鍵在 fieldnames 中找不到,則可選參數 extrasaction 用于指定要執行的操作。如果將其設置為'raise'(默認值),則會引發ValueError。 如果將其設置為'ignore',則字典中的其他鍵值將被忽略。 所有其他可選或關鍵字參數都傳遞給底層的writer實例。注意,與
DictReader類不同,DictWriter類的 fieldnames 參數不是可選參數。一個簡短的用法示例:
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'})
-
class
csv.unix_dialect? unix_dialect類定義了在 UNIX 系統上生成的 CSV 文件的常規屬性,即使用'\n'作為換行符,且所有字段都有引號包圍。它在變種注冊表中的名稱是'unix'。3.2 新版功能.
-
class
csv.Sniffer? Sniffer類用于推斷 CSV 文件的格式。Sniffer類提供了兩個方法:
使用 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_NONE? 指示
writer對象不使用引號引出字段。當 定界符 出現在輸出數據中時,其前面應該有 轉義符。如果未設置 轉義符,則遇到任何需要轉義的字符時,writer 都會拋出Error異常。指示
reader不對引號字符進行特殊處理。
csv 模塊定義了以下異常:
-
exception
csv.Error? 該異常可能由任何發生錯誤的函數拋出。
變種與格式參數?
為了更容易指定輸入和輸出記錄的格式,特定的一組格式參數組合為一個 dialect(變種)。一個 dialect 是一個 Dialect 類的子類,它具有一組特定的方法和一個 validate() 方法。創建 reader 或 writer 對象時,程序員可以將某個字符串或 Dialect 類的子類指定為 dialect 參數。要想補充或覆蓋 dialect 參數,程序員還可以單獨指定某些格式參數,這些參數的名稱與下面 Dialect 類定義的屬性相同。
Dialect 類支持以下屬性:
-
Dialect.delimiter? 一個用于分隔字段的單字符,默認為
','。
-
Dialect.doublequote? 控制出現在字段中的 引號字符 本身應如何被引出。當該屬性為
True時,雙寫引號字符。如果該屬性為False,則在 引號字符 的前面放置 轉義符。默認值為True。在輸出時,如果 doublequote 是
False,且 轉義符 未指定,且在字段中發現 引號字符 時,會拋出Error異常。
-
Dialect.escapechar? 一個用于 writer 的單字符,用來在 quoting 設置為
QUOTE_NONE的情況下轉義 定界符,在 doublequote 設置為False的情況下轉義 引號字符。在讀取時,escapechar 去除了其后所跟字符的任何特殊含義。該屬性默認為None,表示禁用轉義。
-
Dialect.lineterminator? 放在
writer產生的行的結尾,默認為'\r\n'。注解
reader經過硬編碼,會識別'\r'或'\n'作為行尾,并忽略 lineterminator。未來可能會更改這一行為。
-
Dialect.quotechar? 一個單字符,用于包住含有特殊字符的字段,特殊字符如 定界符 或 引號字符 或換行符。默認為
'"'。
-
Dialect.quoting? 控制 writer 何時生成引號,以及 reader 何時識別引號。該屬性可以等于任何
QUOTE_*常量(參見 模塊內容 段落),默認為QUOTE_MINIMAL。
Reader 對象?
Reader 對象(DictReader 實例和 reader() 函數返回的對象)具有以下公開方法:
-
csvreader.__next__()? 返回 reader 的可迭代對象的下一行,返回值可能是列表(由
reader()返回的對象)或字典(由DictReader返回的對象),解析是根據當前設置的變種進行的。通常應該這樣調用它:next(reader)。
Reader 對象具有以下公開屬性:
-
csvreader.dialect? 變種描述,只讀,供解析器使用。
-
csvreader.line_num? 源迭代器已經讀取了的行數。它與返回的記錄數不同,因為記錄可能跨越多行。
DictReader 對象具有以下公開屬性:
-
csvreader.fieldnames? 字段名稱。如果在創建對象時未傳入字段名稱,則首次訪問時或從文件中讀取第一條記錄時會初始化此屬性。
Writer 對象?
Writer 對象(DictWriter 實例和 writer() 函數返回的對象)具有下面的公開方法。對于 Writer 對象,行 必須是(一組可迭代的)字符串或數字。對于 DictWriter 對象,行 必須是一個字典,這個字典將字段名映射為字符串或數字(數字要先經過 str() 轉換類型)。請注意,輸出的復數會有括號包圍。這樣其他程序讀取 CSV 文件時可能會有一些問題(假設它們完全支持復數)。
-
csvwriter.writerow(row)? 將 row 形參寫入 writer 的文件對象,并按照當前設定形式進行格式化。
在 3.5 版更改: 開始支持任意類型的迭代器。
-
csvwriter.writerows(rows)? 將 rows*(即能迭代出多個上述 *row 對象的迭代器)中的所有元素寫入 writer 的文件對象,并根據當前設置的變種進行格式化。
Writer 對象具有以下公開屬性:
-
csvwriter.dialect? 變種描述,只讀,供 writer 使用。
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())。要使用其他編碼來解碼文件,請使用 open 的 encoding 參數:
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')
Reader 的更高級用法——捕獲并報告錯誤:
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)
備注
