csv
--- CSV File Reading and Writing¶
ソースコード: 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)。
モジュールコンテンツ¶
csv
モジュールでは以下の関数を定義しています:
- csv.reader(csvfile, dialect='excel', **fmtparams)¶
Return a reader object that will process lines from the given csvfile. A csvfile must be an iterable of strings, each in the reader's defined csv format. A csvfile is most commonly a file-like object or list. If csvfile is a file object, it should be opened with
newline=''
. [1] An optional dialect parameter can be given which is used to define a set of parameters specific to a particular CSV dialect. It may be an instance of a subclass of theDialect
class or one of the strings returned by thelist_dialects()
function. The other optional fmtparams keyword arguments can be given to override individual formatting parameters in the current dialect. For full details about the dialect and formatting parameters, see section 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(f, fieldnames=None, restkey=None, restval=None, dialect='excel', *args, **kwds)¶
通常の reader のように動作しますが、個々の行の情報を
dict
にマップするオブジェクトを生成します。マップのキーは省略可能な fieldnames パラメータで与えられます。The fieldnames parameter is a sequence. If fieldnames is omitted, the values in the first row of file f will be used as the fieldnames. Regardless of how the fieldnames are determined, the dictionary preserves their original ordering.
行がフィールド名より多くのフィールドを持っていた場合、残りのデータはリストに入れられて、 restkey により指定されたフィールド名 (デフォルトでは
None
) で保存されます。空白でない行がフィールド名よりも少ないフィールドしか持たない場合、足りない値は restval の値 (デフォルトはNone
) によって埋められます。その他の省略可能またはキーワード形式のパラメータは、ベースになっている
reader
インスタンスに渡されます。バージョン 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)¶
通常の writer のように動作しますが、辞書を出力行にマップするオブジェクトを生成します。 fieldnames パラメータは、
writerow()
メソッドに渡された辞書の値がどのような順番でファイル f に書かれるかを指定するキーのsequence
です。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.Dialect¶
Dialect
クラスはコンテナクラスです。その属性に、ダブルクォート、空白文字、デリミタなどの扱い方に関する情報を含みます。CSV には厳密な規格がないため、アプリケーションによって生成される CSV データはそれぞれ僅かに異なります。Dialect
クラスのインスタンスはreader
とwriter
のインスタンスの挙動を定義します。All available
Dialect
names are returned bylist_dialects()
, and they can be registered with specificreader
andwriter
classes through their initializer (__init__
) functions like this:import csv with open('students.csv', 'w', newline='') as csvfile: writer = csv.writer(csvfile, dialect='unix')
- 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
クラスではメソッドを二つ提供しています:- sniff(sample, delimiters=None)¶
与えられた sample を解析し、発見されたパラメータを反映した
Dialect
サブクラスを返します。オプションの delimiters パラメータを与えた場合、有効なデリミタ文字を含んでいるはずの文字列として解釈されます。
- has_header(sample)¶
Analyze the sample text (presumed to be in CSV format) and return
True
if the first row appears to be a series of column headers. Inspecting each column, one of two key criteria will be considered to estimate if the sample contains a header:2番目からn番目の行は数値を含みます。
the second through n-th rows contain strings where at least one value's length differs from that of the putative header of that column.
1 行目の後の 20 行がサンプリングされます。半分以上の行 + 列が条件を満たす場合、
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_MINIMAL¶
writer
オブジェクトに対し、 delimiter 、 quotechar または lineterminator に含まれる任意の文字のような特別な文字を含むフィールドだけをクオートするように指示します。
- csv.QUOTE_NONNUMERIC¶
writer
オブジェクトに対し、全ての非数値フィールドをクオートするように指示します。Instructs the reader to convert all non-quoted fields to type float.
- csv.QUOTE_NONE¶
writer
オブジェクトに対し、フィールドを決してクオートしないように指示します。現在の delimiter が出力データ中に現れた場合、現在設定されている escapechar 文字が前に付けられます。 escapechar がセットされていない場合、エスケープが必要な文字に遭遇した writer はError
を送出します。Instructs
reader
to perform no special processing of quote characters.
csv
モジュールでは以下の例外を定義しています:
- exception csv.Error¶
全ての関数において、エラーが検出された際に送出される例外です。
Dialect クラスと書式化パラメータ¶
To make it easier to specify the format of input and output records, specific
formatting parameters are grouped together into dialects. A dialect is a
subclass of the Dialect
class containing various attributes
describing the format of the CSV file. When creating reader
or
writer
objects, the programmer can specify a string or a subclass of
the Dialect
class as the dialect parameter. In addition to, or instead
of, the dialect parameter, the programmer can also specify individual
formatting parameters, which have the same names as the attributes defined below
for the Dialect
class.
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
で、エスケープを行ないません。バージョン 3.11 で変更: 空の escapechar は許可されていません。
- Dialect.lineterminator¶
writer
が作り出す各行を終端する際に用いられる文字列です。デフォルトでは'\r\n'
です。注釈
reader
は'\r'
または'\n'
のどちらかを行末と認識するようにハードコードされており、 lineterminator を無視します。この振る舞いは将来変更されるかもしれません。
- Dialect.quotechar¶
delimiter や quotechar といった特殊文字を含むか、改行文字を含むフィールドをクオートする際に用いられる 1 文字からなる文字列です。デフォルトでは
'"'
です。バージョン 3.11 で変更: 空の quotechar は許可されていません。
- Dialect.quoting¶
クオートがいつ writer によって生成されるか、また reader によって認識されるかを制御します。QUOTE_* constants のいずれかをとることができ、デフォルトでは
QUOTE_MINIMAL
です。
reader オブジェクト¶
reader オブジェクト(DictReader
インスタンス、および reader()
関数によって返されたオブジェクト) は、以下の public なメソッドを持っています:
- csvreader.__next__()¶
reader の反復可能なオブジェクトから、現在の表現形式 (
Dialect
) に基づいて次の行を解析してリスト(オブジェクトがreader()
から返された場合)または辞書 (DictReader
のインスタンスの場合)として返します。通常はnext(reader)
のようにして呼び出すことになります。
reader オブジェクトには以下の公開属性があります:
- csvreader.dialect¶
パーサで使われる表現形式の読み出し専用の記述です。
- csvreader.line_num¶
ソースイテレータから読んだ行数です。この数は返されるレコードの数とは、レコードが複数行に亘ることがあるので、一致しません。
DictReader オブジェクトは、以下の public な属性を持っています:
- DictReader.fieldnames¶
オブジェクトを生成するときに渡されなかった場合、この属性は最初のアクセス時か、ファイルから最初のレコードを読み出したときに初期化されます。
writer オブジェクト¶
writer
オブジェクト(DictWriter
インスタンス、および writer()
関数によって返されたオブジェクト) は、以下の public なメソッドを持っています: row には、 writer
オブジェクトの場合には文字列か数値のイテラブルを指定し、 DictWriter
オブジェクトの場合はフィールド名をキーとして対応する文字列か数値を格納した辞書オブジェクトを指定します(数値は str()
で変換されます)。複素数を出力する場合、値をかっこで囲んで出力します。このため、CSV ファイルを読み込むアプリケーションで(そのアプリケーションが複素数をサポートしていたとしても)問題が発生する場合があります。
- csvwriter.writerow(row)¶
現在の表現形式 (
Dialect
.)に沿ってフォーマットされた row パラメータを writer のファイルオブジェクトに書き込みます。ファイルオブジェクトの write メソッドを呼び出した際の戻り値を返します。バージョン 3.5 で変更: 任意のイテラブルのサポートの追加。
- csvwriter.writerows(rows)¶
rows 引数 (上で解説した row オブジェクトのイテラブル) の全ての要素を現在の表現形式に基づいて書式化し、writer のファイルオブジェクトに書き込みます。
writer オブジェクトには以下の公開属性があります:
- csvwriter.dialect¶
writer で使われる表現形式の読み出し専用の記述です。
DictWriter のオブジェクトは以下の public メソッドを持っています:
- DictWriter.writeheader()¶
Write a row with the field names (as specified in the constructor) to the writer's file object, formatted according to the current dialect. Return the return value of the
csvwriter.writerow()
call used internally.バージョン 3.2 で追加.
バージョン 3.8 で変更:
writeheader()
は内部的に利用しているcsvwriter.writerow()
メソッドの返り値を返すようになりました。
使用例¶
最も簡単な 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.getencoding()
を参照)。他のエンコーディングを用いてデコードするには、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)
脚注