>>> 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 object),其負責在給定的類檔案物件 (file-like object) 上將使用者的資料轉換為分隔字串 (delimited string)。csvfile 可以為具有 write()
method 的任何物件。若 csvfile 為一個檔案物件,它應該使用 newline=''
開啟 。dialect 為一個可選填的參數,可以用為特定的 CSV dialect 定義一組參數。它可能為 Dialect
的一個子類別的實例或是由 list_dialects()
函式回傳的多個字串中的其中之一。另一個可選填的關鍵字引數 fmtparams 可以在這個 dialect 中覆寫個別的格式化參數。關於 dialect 及格式化參數的完整說明,請見段落 变种与格式参数。為了更容易與有實作 DB API 的模組互相接合,None
值會被寫成空字串。雖然這不是一個可逆的變換,這使得dump (傾印) SQL NULL 資料值到 CSV 檔案上就無需讓 cursor.fetch*
呼叫回傳的資料進行預處理 (preprocessing)。其餘非字串的資料則會在寫入之前用 str()
函式進行字串化 (stringify)。
一個簡短的用法範例:
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.field_size_limit([new_limit])
回傳當前的剖析器 (parser) 允許的最大字串大小。如果 new_limit 被給定,則會變成新的最大字串大小。
csv
模組定義了下列的類別:
class csv.DictReader(f, fieldnames=None, restkey=None, restval=None, dialect='excel', *args, **kwds)
建立一個物件,其運作上就像一般的讀取器,但可以將每一列資訊 map (對映) 到 dict
中,可以透過選填的參數 fieldnames 設定 key。
參數 fieldnames 是一個 sequence。如果 fieldnames 被省略了,檔案 f 中第一列的值會被當作欄位標題。不管欄位標題是如何決定的,dictionary都會保留原始的排序。
如果一列資料中的欄位比欄位標題還多,其餘的資料及以 restkey (預設為 None
)特指的欄位標題會放入列表當中並儲存。如果一個非空的 (non-blank) 列中的欄位比欄位標題還少,缺少的值則會填入 restval (預設為 None
)的值。
所有其他選填的引數或關鍵字引數皆會傳遞至下層的 reader
實例。
如果傳遞至 fieldnames 的引數是個疊代器,則會被迫成為一個 list
。
在 3.6 版的變更: 回傳的列已成為型別 OrderedDict
。
在 3.8 版的變更: 回傳的列已成為型別 dict
。
一個簡短的用法範例:
>>> 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)
{'first_name': 'John', 'last_name': 'Cleese'}
class csv.DictWriter(f, fieldnames, restval='', extrasaction='raise', dialect='excel', *args, **kwds)
建立一個物件,其運作上就像一般的寫入器,但可以將 dictionary map 到輸出的列上。參數 fieldnames 是一個鍵值的 sequence
且可以辨識 dictionary 中傳遞至 writerow()
method 寫入至檔案 f 中的值。如果 dictionary 中缺少了 fieldnames 的鍵值,則會寫入選填的參數 restval 的值。如果傳遞至 writerow()
method 的 dictionary 包含了一個 fieldnames 中不存在的鍵值,選填的參數 extrasaction 可以指出該執行的動作。如果它被設定為 'raise'
,預設會觸發 ValueError
。如果它被設定為 'ignore'
,dictionary 中額外的值會被忽略。其他選填的引數或關鍵字引數皆會傳遞至下層的 writer
實例。
請記得這不像類別 DictReader
,在類別 DictWriter
中,參數 fieldnames 並不是選填的。
如果傳遞至 fieldnames 的引數是個疊代器,則會被迫成為一個 list
。
一個簡短的用法範例:
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.Dialect
類別 Dialect
是一個容器類別,其屬性 (attribute) 包含如何處理雙引號、空白、分隔符號等資訊。由於缺少一個嚴謹的 CSV 技術規範,不同的應用程式會產出有巧妙不同的 CSV 資料。Dialect
實例定義了 reader
以及 writer
的實例該如何表示。
所有可用的 Dialect
名稱會透過 list_dialects()
回傳,且它們可以透過特定 reader
及 writer
類別的初始器 (initializer, __init__
) 函式進行註冊,就像這樣:
import csv
with open('students.csv', 'w', newline='') as csvfile:
writer = csv.writer(csvfile, dialect='unix')
^^^^^^^^^^^^^^
class csv.unix_dialect
類別 unix_dialect
定義了透過 UNIX 系統產生的 CSV 檔案的慣用屬性,換句話說,使用 '\n'
作為換行符號且所有欄位都被引號包覆起來。它被註冊的 dialect 名稱為 'unix'
。
在 3.2 版新加入.
has_header(sample)
分析 sample 文本(假定为 CSV 格式),如果发现其首行为一组列标题则返回 True
。 在检查每一列时,将考虑是否满足两个关键标准之一来估计 sample 是否包含标题:
第二至第 n 行包含数字值
第二至第 n 行包含字符串值,其中至少有一个值的长度与该列预期标题的长度不同。
会对第一行之后的二十行进行采样;如果有超过一半的列 + 行符合标准,则返回 True
。
此方法是一个粗略的启发式方式,有可能产生错误的真值和假值。
使用 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_ALL
指示 writer
对象给所有字段加上引号。
csv.QUOTE_NONE
指示 writer
对象不使用引号引出字段。当 定界符 出现在输出数据中时,其前面应该有 转义符。如果未设置 转义符,则遇到任何需要转义的字符时,writer 都会抛出 Error
异常。
指示 reader
对象不对引号字符执行特殊处理。
csv.QUOTE_NOTNULL
指示 writer
对象为所有不为 None
的字段加引号。 这类似于 QUOTE_ALL
,区别是如果一个字段值为 None
则会写入一个(不带引号的)空字符串。
指示 reader
对象将(不带引号的)空字段解读为 None 并在其他情况下采取与 QUOTE_ALL
相同的行为。
csv.QUOTE_STRINGS
指示 writer
对象总是为字符串字段加引号。 这类似于 QUOTE_NONNUMERIC
,区别是如果一个字段值为 None
则会写入一个(不带引号的)空字符串。
指示 reader
对象将(不带引号的)空字符串解读为 None
并在其他情况下采取与 QUOTE_NONNUMERIC
相同的行为。
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
,表示禁用转义。
在 3.11 版的變更: 不允许空的 escapechar。
csvreader.__next__()
返回 reader 的可迭代对象的下一行,它可以是一个列表(如果对象是由 reader()
返回)或字典(如果是一个 DictReader
实例),根据当前 Dialect
来解析。 通常你应当以 next(reader)
的形式来调用它。
Reader 对象具有以下公开属性:
csvreader.dialect
变种描述,只读,供解析器使用。
Writer 对象
Writer
对象(DictWriter
实例和 writer()
函数返回的对象)具有下面的公开方法。对于 Writer
对象,行 必须是(一组可迭代的)字符串或数字。对于 DictWriter
对象,行 必须是一个字典,这个字典将字段名映射为字符串或数字(数字要先经过 str()
转换类型)。请注意,输出的复数会有括号包围。这样其他程序读取 CSV 文件时可能会有一些问题(假设它们完全支持复数)。
csvwriter.writerow(row)
将 row 形参写入到 writer 的文件对象,根据当前 Dialect
进行格式化。 返回对下层文件对象的 write 方法的调用的返回值。
在 3.5 版的變更: 新增對任意 iterable 的支援。
csvwriter.writerows(rows)
将 rows*(即能迭代出多个上述 *row 对象的迭代器)中的所有元素写入 writer 的文件对象,并根据当前设置的变种进行格式化。
Writer 对象具有以下公开属性:
csvwriter.dialect
变种描述,只读,供 writer 使用。
DictWriter 对象具有以下公开方法:
DictWriter.writeheader()
在 writer 的文件对象中,写入一行字段名称(字段名称在构造函数中指定),并根据当前设置的变种进行格式化。本方法的返回值就是内部使用的 csvwriter.writerow()
方法的返回值。
在 3.2 版新加入.
在 3.8 版的變更: 现在 writeheader()
也返回其内部使用的 csvwriter.writerow()
方法的返回值。
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 文件供读取,因此在默认情况下将使用系统默认编码格式 (参见 locale.getencoding()
) 把文件解码至 unicode。 要使用其他编码格式来解码文件,请使用 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)
[1]
(1,2)
如果没有指定 newline=''
,则嵌入引号中的换行符将无法正确解析,并且在写入时,使用 \r\n
换行的平台会有多余的 \r
写入。由于 csv 模块会执行自己的(通用)换行符处理,因此指定 newline=''
应该总是安全的。
© 版權 2001-2023, Python Software Foundation.
This page is licensed under the Python Software Foundation License Version 2.
Examples, recipes, and other code in the documentation are additionally licensed under the Zero Clause BSD License.
See History and License for more information.
The Python Software Foundation is a non-profit corporation.
Please donate.
最後更新於 9月 12, 2023。
Found a bug?