14.1. csv
— CSV ファイルの読み書き¶
ソースコード: Lib/csv.py
CSV (Comma Separated Values、カンマ区切り値列) と呼ばれる形式は、 スプレッドシートやデータベース間でのデータのインポートやエクスポートにおける最も一般的な形式です。 CSVフォーマットは、 RFC 4180 によって標準的な方法でフォーマットを記述する試みが行われる以前から長年使用されました。明確に定義された標準がないということは、異なるアプリケーション によって生成されたり取り込まれたりするデータ間では、しばしば微妙な違いが発生するということを意味します。こうした違いのために、複数のデータ源から得られた CSV ファイルを処理する作業が鬱陶しいものになることがあります。とはいえ、デリミタ (delimiter) やクオート文字の 相違はあっても、全体的な形式は十分似通っているため、こうしたデータを効率的に操作し、データの読み書きにおける細々としたことをプログラマ から隠蔽するような単一のモジュールを書くことは可能です。
csv
モジュールでは、CSV 形式で書かれたテーブル状のデータを読み書きするためのクラスを実装しています。このモジュールを使うことで、プログラマは Excel で使われている CSV 形式に関して詳しい知識をもっていなくても、 “このデータを Excel で推奨されている形式で書いてください” とか、 “データを Excel で作成されたこのファイルから読み出してください” と言うことができます。プログラマはまた、他のアプリケーションが解釈できる CSV 形式を記述したり、独自の特殊な目的をもった CSV 形式を定義することができます。
csv
モジュールの reader
および writer
オブジェクトはシーケンス型を読み書きします。プログラマは DictReader
や DictWriter
クラスを使うことで、データを辞書形式で読み書きすることもできます。
参考
- PEP 305 - CSV File API
Python へのこのモジュールの追加を提案している Python 改良案 (PEP: Python Enhancement Proposal)。
14.1.1. モジュールコンテンツ¶
csv
モジュールでは以下の関数を定義しています:
-
csv.
reader
(csvfile, dialect='excel', **fmtparams)¶ 与えられた csvfile 内の行を反復処理するような reader オブジェクトを返します。 csvfile はイテレータ(iterator)プロトコルをサポートし、
__next__()
メソッドが呼ばれた際に常に文字列を返すような任意のオブジェクトにすることができます — ファイルオブジェクト でもリストでも構いません。 csvfile がファイルオブジェクトの場合、newline=''
として開くべきです。 [1] オプションとして dialect パラメタを与えることができ、特定の CSV 表現形式 (dialect) 特有のパラメタの集合を定義するために使われます。 dialect 引数はDialect
クラスのサブクラスのインスタンスか、list_dialects()
関数が返す文字列の一つにすることができます。別のオプションである fmtparams キーワード引数は、現在の表現形式における個々の書式パラメタを上書きするために与えることができます。表現形式および書式化パラメタの詳細については、 Dialect クラスと書式化パラメタ 節を参照してください。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)を指定することができます。 dialect パラメタはDialect
クラスのサブクラスのインスタンスか、list_dialects()
関数が返す文字列の1つにすることができます。別のオプション引数である fmtparams キーワード引数は、現在の表現形式における個々の書式パラメタを上書きするために与えることができます。dialect と書式パラメタについての詳細は、 Dialect クラスと書式化パラメタ 節を参照してください。 DB API を実装するモジュールとのインタフェースを可能な限り容易にするために、None
は空文字列として書き込まれます。この処理は可逆な変換ではありませんが、SQL で NULL データ値を 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]])¶ dialect を name と関連付けます。 name は文字列でなければなりません。表現形式(dialect)は
Dialect
のサブクラスを渡すか、またはキーワード引数 fmtparams 、もしくは両方で指定できますが、キーワード引数の方が優先されます。表現形式と書式化パラメタについての詳細は、 Dialect クラスと書式化パラメタ 節を参照してください。
-
csv.
get_dialect
(name)¶ name に関連づけられた表現形式を返します。 name が表現形式名でない場合には
Error
を送出します。この関数は不変のDialect
を返します。
-
csv.
list_dialects
()¶ 登録されている全ての表現形式を返します。
-
csv.
field_size_limit
([new_limit])¶ パーサが許容する現在の最大フィールドサイズを返します。new_limit が渡されたときは、その値が新しい上限になります。
csv
モジュールでは以下のクラスを定義しています:
-
class
csv.
DictReader
(csvfile, fieldnames=None, restkey=None, restval=None, dialect='excel', *args, **kwds)¶ 省略可能な fieldnames パラメタで与えられたキーを読み出された情報に対応付ける他は正規の reader のように動作するオブジェクトを生成します。 fieldnames パラメタは
sequence
で各要素が入力データのフィールドに関連づけられます。 fieldnames パラメタが無い場合には、 csvfile の最初の行の値がフィールド名として利用されます。読み出された行が fieldnames のシーケンスよりも多くのフィールドを持っていた場合、残りのフィールドデータは restkey の値をキーとするシーケンスに追加されます。読み出された行が fieldnames のシーケンスよりも少ないフィールドしか持たない場合、残りのキーはオプションの restval パラメタに指定された値を取ります。その他の省略可能またはキーワード形式のパラメタはベースになっているreader
のインスタンスに渡されます。短い利用例:
>>> import csv >>> with open('names.csv') as csvfile: ... reader = csv.DictReader(csvfile) ... for row in reader: ... print(row['first_name'], row['last_name']) ... Baked Beans Lovely Spam Wonderful Spam
-
class
csv.
DictWriter
(csvfile, fieldnames, restval='', extrasaction='raise', dialect='excel', *args, **kwds)¶ 辞書を出力行に対応付ける他は正規の writer のように動作するオブジェクトを生成します。 fieldnames パラメタは、辞書中の
writerow()
メソッドに渡される値がどの順番で csvfile に書き出されるかを指定するsequence
です。オプションの restval パラメタは、 fieldnames 内のキーが辞書中にない場合に書き出される値を指定します。writerow()
メソッドに渡された辞書に、 fieldnames 内には存在しないキーが入っている場合、オプションの extrasaction パラメタでどのような動作を行うかを指定します。この値が'raise'
に設定されている場合ValueError
が送出されます。'ignore'
に設定されている場合、辞書の余分の値は無視されます。その他のパラメタはベースになっているwriter
のインスタンスに渡されます。DictReader
クラスとは違い、DictWriter
の fieldnames パラメータは省略可能ではありません。Pythonのdict
オブジェクトは整列されていないので、列が csvfile に書かれるべき順序を推定するための十分な情報はありません。短い利用例:
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'})
-
class
csv.
Dialect
¶ Dialect
クラスはコンテナクラスで、基本的な用途としては、その属性を特定のreader
やwriter
インスタンスのパラメタを定義するために用います。
-
class
csv.
excel
¶ excel
クラスは Excel で生成される CSV ファイルの通常のプロパティを定義します。これは'excel'
という名前の dialect として登録されています。
-
class
csv.
excel_tab
¶ excel_tab
クラスは Excel で生成されるタブ分割ファイルの通常のプロパティを定義します。これは'excel-tab'
という名前の dialect として登録されています。
-
class
csv.
unix_dialect
¶ unix_dialect
クラスは UNIX システムで生成される CSV ファイルの通常のプロパティ (行終端記号として'\n'
を用い全てのフィールドをクォートするもの) を定義します。これは'unix'
という名前の dialect として登録されています。バージョン 3.2 で追加.
-
class
csv.
Sniffer
¶ Sniffer
クラスは CSV ファイルの書式を推理するために用いられるクラスです。Sniffer
クラスではメソッドを二つ提供しています:
Sniffer
の利用例:
with open('example.csv') 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_MINIMAL
¶ writer
オブジェクトに対し、 delimiter 、 quotechar または lineterminator に含まれる任意の文字のような特別な文字を含むフィールドだけをクオートするように指示します。
-
csv.
QUOTE_NONNUMERIC
¶ writer
オブジェクトに対し、全ての非数値フィールドをクオートするように指示します。reader
に対しては、クオートされていない全てのフィールドを float 型に変換するよう指示します。
-
csv.
QUOTE_NONE
¶ writer
オブジェクトに対し、フィールドを決してクオートしないように指示します。現在の delimiter が出力データ中に現れた場合、現在設定されている escapechar 文字が前に付けられます。 escapechar がセットされていない場合、エスケープが必要な文字に遭遇した writer はError
を送出します。reader
に対しては、クオート文字の特別扱いをしないように指示します。
csv
モジュールでは以下の例外を定義しています:
-
exception
csv.
Error
¶ 全ての関数において、エラーが検出された際に送出される例外です。
14.1.2. Dialect クラスと書式化パラメタ¶
レコードに対する入出力形式の指定をより簡単にするために、特定の書式化パラメタは表現形式 (dialect) にまとめてグループ化されます。表現形式は Dialect
クラスのサブクラスで、様々なクラス特有のメソッドと、 validate()
メソッドを一つ持っています。 reader
または writer
オブジェクトを生成するとき、プログラマは文字列または Dialect
クラスのサブクラスを表現形式パラメタとして渡さなければなりません。さらに、 dialect パラメタの代りに、プログラマは上で定義されている属性と同じ名前を持つ個々の書式化パラメタを Dialect
クラスに指定することができます。
Dialect は以下の属性をサポートしています:
-
Dialect.
delimiter
¶ フィールド間を分割するのに用いられる 1 文字からなる文字列です。デフォルトでは
','
です。
-
Dialect.
doublequote
¶ フィールド内に現れた quotechar のインスタンスで、クオートではないその文字自身でなければならない文字をどのようにクオートするかを制御します。
True
の場合、この文字は二重化されます。False
の場合、 escapechar は quotechar の前に置かれます。デフォルトではTrue
です。出力においては、 doublequote が
False
で escapechar がセットされていない場合、フィールド内に quotechar が現れるとError
が送出されます。
-
Dialect.
escapechar
¶ writer が、 quoting が
QUOTE_NONE
に設定されている場合に delimiter をエスケープするため、および、 doublequote がFalse
の場合に quotechar をエスケープするために用いられる、 1 文字からなる文字列です。読み込み時には escapechar はそれに引き続く文字の特別な意味を取り除きます。デフォルトではNone
で、エスケープを行ないません。
-
Dialect.
lineterminator
¶ writer
が作り出す各行を終端する際に用いられる文字列です。デフォルトでは'\r\n'
です。注釈
reader
は'\r'
または'\n'
のどちらかを行末と認識するようにハードコードされており、 lineterminator を無視します。この振る舞いは将来変更されるかもしれません。
-
Dialect.
quotechar
¶ delimiter や quotechar といった特殊文字を含むか、改行文字を含むフィールドをクオートする際に用いられる 1 文字からなる文字列です。デフォルトでは
'"'
です。
-
Dialect.
quoting
¶ クオートがいつ writer によって生成されるか、また reader によって認識されるかを制御します。
QUOTE_*
定数のいずれか (モジュールコンテンツ 節参照) をとることができ、デフォルトではQUOTE_MINIMAL
です。
14.1.3. reader オブジェクト¶
reader オブジェクト(DictReader
インスタンス、および reader()
関数によって返されたオブジェクト) は、以下の public なメソッドを持っています:
-
csvreader.
__next__
()¶ reader の反復可能なオブジェクトから、現在の表現形式に基づいて次の行を解析して返します。通常は
next(reader)
のようにして呼び出すことになります。
reader オブジェクトには以下の公開属性があります:
-
csvreader.
dialect
¶ パーサで使われる表現形式の読み取り専用の記述です。
-
csvreader.
line_num
¶ ソースイテレータから読んだ行数です。この数は返されるレコードの数とは、レコードが複数行に亘ることがあるので、一致しません。
DictReader オブジェクトは、以下のpublicな属性を持っています:
-
csvreader.
fieldnames
¶ オブジェクトを生成するときに渡されなかった場合、この属性は最初のアクセス時か、ファイルから最初のレコードを読み出したときに初期化されます。
14.1.4. writer オブジェクト¶
Writer
オブジェクト(DictWriter
インスタンス、および writer()
関数によって返されたオブジェクト) は、以下の public なメソッドを持っています: row には、 Writer
オブジェクトの場合には文字列か数値のイテラブルを指定し、 DictWriter
オブジェクトの場合はフィールド名をキーとして対応する文字列か数値を格納した辞書オブジェクトを指定します(数値は str()
で変換されます)。複素数を出力する場合、値をかっこで囲んで出力します。このため、CSV ファイルを読み込むアプリケーションで(そのアプリケーションが複素数をサポートしていたとしても)問題が発生する場合があります。
-
csvwriter.
writerow
(row)¶ row パラメタを現在の表現形式に基づいて書式化し、writer のファイルオブジェクトに書き込みます。
バージョン 3.5 で変更: 任意のイテラブルのサポートの追加。
-
csvwriter.
writerows
(rows)¶ rows 引数(上記 row のリスト)全てを現在の表現形式に基づいて書式化し、writer のファイルオブジェクトに書き込みます。
writer オブジェクトには以下の公開属性があります:
-
csvwriter.
dialect
¶ writer で使われる表現形式の読み取り専用の記述です。
DictWriter のオブジェクトは以下の public メソッドを持っています:
-
DictWriter.
writeheader
()¶ (コンストラクタで指定された)フィールド名の行を出力します。
バージョン 3.2 で追加.
14.1.5. 使用例¶
最も簡単な 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 ファイルの読み込みに使われるため、ファイルはデフォルトではシステムのデフォルトエンコーディングでユニコード文字列にデコードされます (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)
脚注
[1] | (1, 2)
|