【ITニュース解説】Comprehensive Guide to File Handling in Python
2025年09月04日に「Dev.to」が公開したITニュース「Comprehensive Guide to File Handling in Python」について初心者にもわかりやすいように丁寧に解説しています。
ITニュース概要
Pythonでファイルを扱い、データを永続的に保存・読み書きする方法を解説する。テキスト・バイナリファイルの種類、安全な開閉、読み書きモード、パス指定法を学ぶ。CSVやバイナリの処理、ファイルポインタ操作まで、SE初心者向けに体系的に紹介する。
ITニュース解説
システムエンジニアを目指す上で、データの扱い方を理解することは非常に重要だ。特に、プログラムが実行されている間だけでなく、永続的にデータを保存しておく「ファイルハンドリング」の技術は、ほとんど全てのアプリケーション開発で必要とされる基本的なスキルと言える。ファイルハンドリングとは、コンピュータのメモリ上だけでなく、ハードディスクやSSDといったストレージデバイスにデータを書き込み、そこから読み出す一連の操作のことだ。これにより、コンピュータの電源を切ってもデータが失われることなく、次回プログラムを実行した際に以前の情報を再利用できるようになる。
Pythonでは、様々な種類のファイルを扱うことができる。主なものとして「テキストファイル」と「バイナリファイル」の2種類がある。テキストファイルは、人間が直接読むことができる形式でデータが保存されているファイルだ。例えば、.txtファイルや、データを特定の区切り文字(カンマやタブなど)で区切って並べた.csv(Comma-Separated Values)や.tsv(Tab-Separated Values)ファイルなどがある。これらは、Excelなどの表計算ソフトで開くと、整理された表形式で内容を確認できることが多い。一方、バイナリファイルは、人間が直接読んでも意味が分からない「バイトの並び」として情報が格納されている。画像ファイルや音声ファイル、プログラムの実行ファイルなどがこれにあたる。Pythonのpickleモジュールを使ってPythonのオブジェクトをファイルに保存する場合も、バイナリファイルとして扱われる。
ファイルにアクセスするには、まずそのファイルを開く必要がある。Pythonでファイルを開くにはopen()関数を使用する。この関数は、ファイル名と操作モードを指定して呼び出し、ファイルオブジェクトと呼ばれるものを作成する。例えば、fileObj = open("myfile.txt", mode="r")と書くと、myfile.txtというファイルを読み込みモード("r")で開くことになる。ファイルを開いた後は、必要な処理を行い、最後にclose()メソッドを呼び出してファイルを閉じることが非常に重要だ。ファイルを閉じないと、書き込んだデータが正しく保存されなかったり、他のプログラムからそのファイルにアクセスできなくなったりするなどの問題が発生する可能性がある。しかし、fileObj.close()を忘れてしまうミスはよくある。そこで推奨されるのが、with open(...) as fileObj:という構文だ。この構文を使うと、withブロック内の処理が完了した時点で、Pythonが自動的にファイルを閉じてくれるため、閉じ忘れの心配がなくなる。これは、ファイルハンドリングにおいて非常に安全で便利な方法だ。
ファイルパスを指定する際には注意が必要だ。Windows環境などでは、ファイルパスの区切り文字にバックスラッシュ(\)が使われるが、Pythonではバックスラッシュは特殊文字の開始を意味することがある。これを回避する方法は二つある。一つは、ファイルパスの文字列の前にrを付けて「raw文字列」(生文字列)として扱う方法だ。r"C:\Temp\data1.txt"のように記述すると、バックスラッシュが特殊な意味を持たず、そのままの文字として扱われる。もう一つは、バックスラッシュを二重にする(\\)方法だ。"C:\\Temp\\data1.csv"のように記述すると、\\が単一のバックスラッシュとして解釈される。
ファイルを開く際に指定する「モード」は、そのファイルに対してどのような操作を許可するかを決定する。モードにはテキストファイルを扱うためのモードと、バイナリファイルを扱うためのモードがある。テキストファイルモードは、例えば'r'(読み込み専用)、'w'(書き込み専用)、'a'(追記専用)などがあり、それぞれにバイナリファイルを扱うための'rb'、'wb'、'ab'といった対応するモードが存在する。
'r' または 'rb' は読み込み専用モードだ。ファイルが存在しない場合はIOErrorというエラーが発生する。
'w' または 'wb' は書き込み専用モードだ。指定したファイルが存在しない場合は新しくファイルが作成される。もしファイルが既に存在し、中にデータがあった場合は、そのデータは全て消去され、新しく書き込むデータで上書きされる。
'a' または 'ab' は追記専用モードだ。ファイルが存在しない場合は新しくファイルが作成される。ファイルが既に存在し、中にデータがあった場合でも、そのデータは保持され、新しく書き込むデータはファイルの末尾に追加される。
'r+' または 'rb+' は読み込みと書き込みの両方が可能なモードだ。'r'モードと同じく、ファイルは事前に存在している必要があり、存在しない場合はエラーになる。このモードでは、既存のファイルを読み込み、その内容を書き換えるといった操作が可能になる。
'w+' または 'wb+' も読み込みと書き込みの両方が可能なモードだ。'w'モードと同じく、ファイルが存在しない場合は作成され、既存のファイルは内容が上書きされて消去される。このモードは、新しいファイルを読み書き両用で作成したい場合や、既存ファイルを完全にリセットして新しい内容で読み書きしたい場合に使う。
'a+' または 'ab+' も読み込みと書き込みの両方が可能なモードだ。'a'モードと同じく、ファイルが存在しない場合は作成され、既存のファイルに書き込む場合は末尾に追記される。このモードは、既存のファイルの末尾にデータを追記しながら、そのファイルの内容を読み込みたい場合に便利だ。
テキストファイルへの書き込みには、主にwrite()とwritelines()の二つのメソッドがある。write(str)メソッドは、一つの文字列をファイルに書き込む。一方、writelines([str])メソッドは、文字列のリストを引数に取り、リスト内の各文字列をファイルに書き込む。このとき、各文字列の末尾に改行文字\nを明示的に加えないと、全ての文字列が一行に連結されてしまうため注意が必要だ。
テキストファイルの読み込みには、read()、readline()、readlines()の三つのメソッドがある。
read(n)メソッドは、ファイルから指定したバイト数nだけデータを読み込み、文字列として返す。引数を省略した場合、ファイル全体を読み込む。
readline(n)メソッドは、ファイルから一行を読み込み、文字列として返す。通常、行末の改行文字\nも含まれる。バイト数nを指定すると、その行の先頭から指定バイト数までを読み込む。
readlines()メソッドは、ファイル全体を読み込み、各行を要素とする文字列のリストとして返す。各要素には行末の改行文字\nが含まれる。
CSVファイルはテキストファイルの一種だが、構造化されたデータを扱うため、Pythonには専用のcsvモジュールが用意されている。csvモジュールを使うと、CSV形式のデータを簡単に読み書きできる。CSVファイルを開く際には、open()関数のnewline=""という引数を指定することが重要だ。これは、OSごとの改行コードの自動変換を防ぎ、CSVファイルのデータが正しく処理されるようにするためだ。CSVファイルを読み込むには、csv.reader()を使ってリーダーオブジェクトを作成し、それをループで処理することで、各行のデータをリストとして取得できる。CSVファイルに書き込むには、csv.writer()を使ってライターオブジェクトを作成し、writerow()メソッドで1行ずつ、またはwriterows()メソッドで複数の行を一度に書き込むことができる。
バイナリファイル、特にPythonのオブジェクトを保存する際には、pickleモジュールが非常に便利だ。pickleモジュールは、Pythonのオブジェクトをバイトストリームに変換してファイルに保存する「ピクル化(シリアライズ)」と、その逆の「非ピクル化(デシリアライズ)」を行う機能を提供する。バイナリファイルへの書き込みはpickle.dump(data, fileObj)で行い、dataというPythonオブジェクトをfileObjというファイルに書き込む。バイナリファイルからの読み込みはpickle.load(fileObj)で行い、ファイルから読み込んだバイトストリームをPythonオブジェクトに変換して返す。ファイルを読み込む際には、EOFErrorが発生するまでループでload()を呼び出すことで、ファイル内の全てのオブジェクトを読み出すことができる。
ファイルポインタの操作も、ファイルハンドリングの高度なテクニックとして知っておくと良いだろう。ファイルポインタは、ファイル内で現在どの位置(バイト単位)で読み書きが行われているかを示す目印だ。
tell()関数は、このファイルポインタの現在の位置を整数値で返す。例えば、ファイルの中間まで読み込んだ後、現在どこまで読んだかを確認したいときに役立つ。
seek(offset, mode)関数は、ファイルポインタを任意の位置に移動させる機能を持つ。offsetは移動させるバイト数、modeは移動の基準となる位置を示す。modeには3つの値がある。
0(デフォルト):ファイルの先頭からの相対位置でオフセットを指定する。
1:ファイルポインタの現在の位置からの相対位置でオフセットを指定する。
2:ファイルの末尾からの相対位置でオフセットを指定する(この場合、offsetは負の値を指定することが多い)。
seek()とtell()関数は、ファイルの特定の部分だけを読み書きしたい場合や、ファイルを効率的に編集したい場合に特に役立つ。
このように、Pythonのファイルハンドリングは、シンプルなテキストファイルから複雑なバイナリファイル、そして構造化されたCSVファイルまで、幅広いデータを柔軟に扱うための多様な機能を提供している。これらの基本を理解し、適切に使いこなすことで、より堅牢で実用的なアプリケーションを開発するための土台を築くことができるだろう。ファイル操作はシステムエンジニアとして日常的に行う作業なので、これらの知識は必ず役立つはずだ。