本記事はアフィリエイトリンクを含みます。Amazon のアソシエイトとして、TechAthletes は適格販売により収入を得ています。価格・割引・在庫は変動するため、最新の条件は各公式サイトでご確認ください。
CSVの「既定」はどの設定を指すのか
CSVを扱うとき、「既定の形式」という言葉だけでは、確認する対象が定まりません。フィールドを何で区切るか、どの文字を引用符にするか、行末をどう書くかという設定があります。一方、Unicodeの文字をどの形式で表現するかという選択もあります。
Pythonのcsv公式文書が説明するdialectは、区切り文字や引用符などの書式パラメーターをまとめたものです。UnicodeのFAQは、UTF-8、UTF-16、UTF-32をUnicodeデータの表現形式として説明しています。この二つを分けると、調べるべき設定が明確になります。
たとえば、csv.readerとcsv.writerの既定のdialectは'excel'です。Pythonの公式文書では、excelクラスはExcelが生成するCSVの一般的な特性を定義するとされています。ここで確認できるのはCSVの書式です。文字の表現については、UTFの説明を別に確認します。
Pythonの文書は、アプリケーションごとにCSVの細かな違いがあることにも触れています。「CSVだから同じ設定で読める」と考える前に、区切り文字や引用符など、入力に使われている書式を確認する必要があります。Python公式文書
readerとwriterで改行の扱いを分けて確認する
csv.readerに渡すのは、文字列のイテラブルです。ファイルオブジェクトを渡す場合、公式文書はnewline=''で開くよう説明しています。csv.writerでファイルへ書き込む場合にも、同じ指定が示されています。
読み取った各行は、通常は文字列のリストとして返されます。QUOTE_NONNUMERICを指定した場合を除き、自動的な型変換は行われません。このオプションを指定すると、引用符で囲まれていないフィールドがfloatへ変換されます。
行末については、書き込みと読み込みの説明を区別することが大切です。lineterminatorは、writerが出力する行の終端に使う文字列で、既定値は'\r\n'です。一方、readerは'\r'または'\n'を行末として認識し、lineterminatorの設定を無視します。公式文書には、このreaderの挙動は将来変わる可能性があるとも書かれています。
したがって、lineterminatorを表示して分かるのはwriter側の行末設定です。その値だけでreader側の改行認識を説明することはできません。読み込みの処理を調べるときは、readerについての記述も確認します。Python公式文書
UTFは文字の表現形式として確認する
UnicodeのFAQでは、UTF-8、UTF-16、UTF-32はいずれもUnicode全体を表現できると説明されています。違いの一つは、表現に使うコード単位のビット数です。
FAQに示された文字の表現は、次のように整理できます。
| 表現形式 | 文字の表現に使う単位 |
|---|---|
| UTF-8 | 1〜4個の8ビットのバイト |
| UTF-16 | 1〜2個の16ビットのコード単位 |
| UTF-32 | 1個の32ビットのコード単位 |
この表が示すのは、文字を表す単位とその個数です。CSVの列を何で区切るか、フィールドをどのように引用するかという規則ではありません。
FAQでは、UTFを、サロゲートコードポイントを除く各Unicodeコードポイントから一意のバイト列へのアルゴリズムによる対応付けと説明しています。また、その変換は可逆であり、Unicodeの文字列をバイト列に変換してから戻すと、元の文字列が得られるとしています。
CSVの書式を調整する場面でも、文字の表現について確認したい場合は、このUTFの説明を別の確認項目として扱います。Unicode FAQ
CSVの書式パラメーターは何を決めるのか
Pythonのdialectには、フィールドの区切り方や引用符の扱いなどを指定する属性があります。代表的な項目を、公式文書に記載された既定値とともに並べると、次のようになります。
| 項目 | 扱う内容 | 既定値 |
|---|---|---|
delimiter |
フィールドを区切る1文字 | ',' |
quotechar |
特殊文字などを含むフィールドを囲む1文字 | '"' |
doublequote |
フィールド内の引用符を重ねて表すか | True |
escapechar |
エスケープに使う1文字 | None |
lineterminator |
writerが出力する行末 | '\r\n' |
skipinitialspace |
区切り文字の直後にある空白を無視するか | False |
strict |
不正なCSV入力でErrorを送出するか |
False |
doublequote=Trueでは、フィールドの中に現れるquotecharを重ねて表します。Falseの場合は、escapecharを前に付けます。出力時にdoublequote=Falseで、escapecharを設定していない状態でフィールド内に引用符があると、Errorが発生します。
引用のタイミングを制御するのはquotingです。通常のquotecharが設定されている場合、既定値はQUOTE_MINIMALで、区切り文字、引用符、改行などの特殊文字を含むフィールドを引用します。QUOTE_ALLを指定すれば、すべてのフィールドを引用します。
dialectを指定しながら、個別の書式パラメーターをキーワード引数で上書きすることもできます。まずdialectを選び、入力や出力に合わせて必要な項目を指定する、という使い方ができます。Python公式文書
ヘッダーと値の変換も別の確認項目にする
CSVを辞書として読み書きする場合、DictReaderとDictWriterでは、フィールド名の指定方法が異なります。
DictReaderでfieldnamesを省略すると、ファイルの最初の行が辞書のキーとして使われ、その行は読み取り結果から除かれます。fieldnamesを指定した場合は、指定した名前がキーとなり、ファイルの最初の行も読み取り結果に含まれます。
行のフィールド数が名前の数より多い場合、余った値はリストとしてrestkeyで指定したキーに格納されます。restkeyの既定値はNoneです。空行ではない行で値が不足している場合は、restvalで補われます。こちらも既定値はNoneです。
一方、DictWriterではfieldnamesが必須で、その並びが出力する値の順序を決めます。辞書に必要なキーがなければ、既定では空文字列が書かれます。指定していないキーが辞書に含まれている場合、既定のextrasaction='raise'ではValueErrorが発生します。'ignore'を指定すると、余分な値は無視されます。
通常のwriterが行う値の変換にも注意が必要です。Noneは空文字列として書き込まれ、この変換は可逆ではありません。それ以外の文字列でない値は、str()で文字列にしてから書き込まれます。これらは、区切り文字やUTFの選択とは別に、データの読み書きで確認したい挙動です。Python公式文書
自分の環境で書式設定を確かめる
登録済みの'excel' dialectは、csv.get_dialect()で取得できます。次のコードは、区切り文字、引用符、writerの行末設定を表示する例です。
python - <<'PY'
import csv
dialect = csv.get_dialect('excel')
print("delimiter:", repr(dialect.delimiter))
print("quotechar:", repr(dialect.quotechar))
print("lineterminator:", repr(dialect.lineterminator))
PY
このコードで確認する対象は、dialectの属性です。表示されたlineterminatorはwriterの設定として読み、readerの改行認識は公式文書の説明と分けて確認します。
個別のパラメーターを指定する例として、次はタブ区切りで行を書き込みます。ファイル名は作業場所に合わせて変更してください。
import csv
with open('./example.tsv', 'w', newline='') as csvfile:
writer = csv.writer(
csvfile,
dialect='excel',
delimiter='\t',
)
writer.writerow(['name', 'quantity'])
writer.writerow(['Sample', 3])
この例で変更している書式パラメーターはdelimiterです。writerow()に渡した行が、指定した書式で出力されます。数字の3のような文字列でない値は、writerの規則に従って文字列へ変換されます。Python公式文書
自動判定の結果にも確認が必要
PythonのSnifferには、サンプルからCSVの書式を推定するsniff()と、先頭行がヘッダーらしいかを推定するhas_header()があります。
sniff()は、サンプルを分析して、検出したパラメーターを反映するDialectのサブクラスを返します。候補となる区切り文字をdelimitersで指定することもできます。
has_header()は、後続の行に数値があるか、文字列の長さが先頭行と異なるかなどを使って推定します。公式文書は、この判定が大まかなヒューリスティックであり、誤検出も見逃しも起こり得ると明記しています。ヘッダーがあると分かっている入力なら、DictReaderのfieldnamesを省略したときの挙動を確認し、列名を別途指定する入力なら、先頭行もデータとして読み込まれることを確認できます。
CSVを扱う際は、区切りと引用、読み書きの改行、ヘッダー、値の変換をそれぞれ確認します。文字の表現についてはUTFの説明を参照することで、どの設定が何を扱っているのかを具体的に追えます。Python公式文書
文字コードを仕組みから押さえたいとき
BOM がなぜ付くのかを UTF-16 のバイト順の問題からたどりたいときは、『[改訂新版]プログラマのための文字コード技術入門』(技術評論社)が使えます。技術評論社の書籍ページ(取得日 2026-10-21)の目次には「UTF-16のバイト順の問題」「BOM(バイト順マーク)」の節があります。例は Java と Ruby で、Python の csv モジュールは扱っていません。

コメント