Pythonのファイル入出力に関わる関数・メソッド(open, close, read, readlines, write, writelines)やwithの使い方について解説します。
ファイル入出力
Pythonに限らずですがプログラミングをする際には、ファイルからデータを読み込んだり、処理結果をファイルに書き込んだりといったファイル入出力処理をよく行います。Pythonではファイル入出力処理に関わる関数やメソッドが各種用意されているためファイル入出力は簡単にできます。
ファイルは開いた(openした)後には閉じる(closeする)ことが必要です。忘れるとプログラムがファイルを開いた状態のままとなってしまい、他プログラムからのアクセスに影響が出ます。Pythonではwithをつかうことで必要な処理が終わったら自動でファイルをクローズすることができます。
本記事では、ファイル入出力に関わる関数・メソッド(open, close, read, readlines, write, writelines)やwithの基本的な使い方を説明します。
ファイル入出力の手順
ファイル入出力をする場合は、基本的に以下の手順になります。
- open関数でファイルを開く
- 「readやreadlineメソッドでデータを読み込む」または「writeやwritelinesメソッドでデータを書き込む」といった入出力処理を実行する
- closeメソッドでファイルを閉じる
以下は、簡単なテキストファイルの書き込み例です。まずはファイル入出力の流れの例を見てみましょう。
input_text = "サンプル" # ファイルを開く(オープン) file = open("sample.txt", "w+", encoding="utf-8") # 文字列の書き込み file.write(input_text) # ファイルを閉じる(クローズ) file.close()
【sample.txtの内容】 サンプル
open関数では、対象ファイルパス、ファイルのモード、文字コードといった情報を指定します。その後、上記例ではwriteメソッドで文字列を書き込んで、closeメソッドでファイルを閉じています。読み込みの場合はメソッドが変わるだけで流れとしては同様です。
ファイルをclose()しないとPythonプログラムがファイルを占有してしまうため、他の人やプログラムが当該ファイルを開こうとしても開けなくなる可能性があります。
そのため、closeは忘れずにする必要がある事を覚えておきましょう。なお、後ほど説明するwithを使って自動でファイルをクローズするようにプログラミングすることが一般的です。
ファイルのモード(mode)
ファイルの入出力では、ファイルをopenする際にモード(mode)を指定します。これにより、読み取り専用、書き込み専用といった制御をすることができます。
主なモード(mode)は以下の種類があります。
種類 | 内容 |
---|---|
r | 読み込み専用(ファイルが存在しない場合エラー。) |
r+ | 読み書き両用(ファイルが存在しない場合エラー。) |
w | 書き込み専用(ファイルが存在しない場合、新規に作成する。) |
w+ | 読み書き両用(オープン時ファイルの内容をクリアする。ファイルが存在しない場合、新規作成する。) |
a | 追記専用(ファイルが存在する場合、末尾に追記する) |
a+ | 読み書き両用(ファイルが存在する場合、末尾に追記する。ファイルが存在しない場合、新規作成する。) |
b | バイナリモード(rやwとセットで指定する: rb, wb) |
「w」モードはファイルの書き込みのたびにデータがクリアされて上書きされるので注意して使いましょう。
また、ログファイルのようにデータを追記していく場合は追記の「a」「a+」モードが使用できます。
withにより自動でファイルをcloseする
ファイルをopenした場合、不要になったらファイルをcloseをすることを忘れないようにしないといけません。しかし、コードが複雑で長いコードになるとクローズを忘れてしまう可能性があります。また、複数コードから参照されるファイルはできる限りオープンされている時間を短くするべきです。
このような問題に対応するためにはwithが一般的に使用されます。withを使用することで、withブロックが終了したタイミングで自動的にファイルをcloseすることができます。
input_text = "サンプル" # withでopenを実行する with open("sample.txt", "w+", encoding="utf-8") as file: # 文字列の書き込み file.write(input_text)
上記のようにwithを使用することで、ファイルのclose忘れを予防できます。ファイル入出力の際にはwithを積極的に使うようにしましょう。
なお、with...asというのはコンテキストマネージャーというもので、コンテキストマネージャーは自分で実装することもできます。「コンテキストマネージャーの基本 ~ with...as命令にオブジェクトを渡すには ~」でコンテキストマネージャーについてまとめていますので興味がある方は参考にしていただければと思います。
コードが終了すれば、ファイルは解放されるため短いコードではcloseを忘れたとしても問題にならないケースがあります。とはいえ、プログラミングでは、ファイルの使用が不要になったタイミングで開放するのが基本です。
C言語等の他言語では、メモリでも同様に確保したら開放することを明示的に実施しないといけません。使ったものは不要になったら片づけるということはPythonに限らずプログラマとして意識するようにしましょう。
テキストファイルの入出力
ファイル入出力で最もよく使うと思われるテキストファイルの入出力について、読み込み、書き込みの実装例を紹介します。
テキストファイルの読み込み
ファイル内容をまとめて取得する read
テキストファイルの内容をまとめて取得する場合は、以下のようにreadメソッドを使用します。
with open("sample_text.txt", "r", encoding="utf-8") as file: data = file.read() print(data)
【実行結果】 Python ファイルの入出力の基本 テキストファイルの入出力
ファイルをopenした後にreadメソッドを使用することでテキストをまとめて読み込むことができます。sample_text.txtは事前に用意しておいたテキストファイルですので、任意のファイルを用意してファイルパスを指定してください。
読み込んだdataを表示してみるとファイルのデータが読み込まれていることが分かるかと思います。
ファイル内容を1文字ずつ取得する read(1)
上記で紹介したようにreadメソッドを引数なしで実行するとファイルの内容をまとめて取得できました。
テキストファイルの文字列を1文字ずつ読み込みたい場合は、以下のようにread(1)とすることで読み込むことができます。
with open("sample_text.txt", "r", encoding="utf-8") as file: data = [] # 一文字ずつ読み込む while d := file.read(1): data.append(d) print(data, "\n") data_str = "".join(data) print(data_str)
【実行結果】 ['P', 'y', 't', 'h', 'o', 'n', '\n', 'フ', 'ァ', 'イ', 'ル', 'の', '入', '出', '力', 'の', '基', '本', '\n', 'テ', 'キ', 'ス', 'ト', 'フ', 'ァ', 'イ', 'ル', 'の', '入', '出', '力'] Python ファイルの入出力の基本 テキストファイルの入出力
上記のように1文字ずつファイル末尾まで繰り返して読み込むことが可能です。
また、全体をつなげたい場合は、"".join(data)のようにすることでつなげることができます。参考までにリストの結合については「リストを結合して文字列にする方法 ~ join ~」でまとめていますので興味があれば参考にしてください。
上記の実装例で使用している「:=」という演算子は、Python3.8から導入された代入式です。公式ドキュメントはこちらを参照ください。
この演算子は、セイウチの目と牙に似ていることから「セイウチ(Walrus)演算子」ともいわれるもので、変数に値を割り当てる構文です。
上記の例をこのセイウチ演算子を使わず書くと以下のようになります。
# セイウチ(Walrs)演算子を使用しない場合 with open("sample_text.txt", "r", encoding="utf-8") as file: data = [] # 一文字ずつ読み込む while True: d = file.read(1) if d == "": break data.append(d) print(data, "\n") data_str = "".join(data) print(data_str)
ファイルの内容を1行ずつ取得する readline
readメソッドは、ファイルの内容をまとめて、または1文字ずつ取得できるメソッドでした。テキストファイルを1行ずつ取り出してリストで処理したい場合は、以下のようにreadlinesメソッドが使用できます。
各行をリストで取得する
readlinesを使用してファイルの各行をリストとして取得する場合には、以下のように使用します。
with open("sample_text.txt", "r", encoding="utf-8") as file: # 1行ずつデータを読み出す data = file.readlines() print(data, "\n") # 取得したデータを出力 for line in data: print(line, end="")
【実行結果】 ['Python\n', 'ファイルの入出力の基本\n', 'テキストファイルの入出力'] Python ファイルの入出力の基本 テキストファイルの入出力
上記の例でdataに入ってくるのは1行ずつの文字列が入ったリスト型です。そのため、for文で順に取り出して処理するといったことが可能になります。
readlinesで取得されるテキストファイルの各行の最後には改行コードが入ったままになります。そのため、print(line, end='')というようにprintの末尾を改行ではなく空文字としています。endを指定しない場合、各行の間に余計な改行が入ってしまいます。
順次1行ずつ取得して処理する場合
readlinesではありませんが、openしたオブジェクトを以下のようにそのままforループで指定すると順次1行ずつ取得することが可能です。1行ずつ処理したい場合等にはこちらの方法も使用できます。
# for文で順次取り出す方法 with open("sample_text.txt", "r", encoding="utf-8") as file: for line in file: print(line, end="")
【実行結果】 Python ファイルの入出力の基本 テキストファイルの入出力
テキストファイルへの書き込み
文字列をテキストファイルへ書き込む write
文字列をテキストファイルを書き込む場合には、以下のようにwriteメソッドを使用します。
data = "Python\nファイルの入出力の基本\nテキストファイルの入出力" # テキストファイルの書き込み with open("sample_text_out_str.txt", "w+", encoding="utf-8") as file: file.write(data)
【sample_text_out_str.txtの内容】 Python ファイルの入出力の基本 テキストファイルの入出力
上記のように、"w+"等の書き込みモードでファイルをopenし、writeメソッドに文字列を渡すだけで簡単にテキストファイルを出力することができます。
文字列のリストをまとめてテキストファイルへ書き込む writelines
文字列のリストをまとめて書き込む場合には、以下のようにwritelinesメソッドを使用します。
data = [ "Python\n", "ファイルの入出力の基本\n", "テキストファイルの入出力", ] # テキストファイルの書き込み with open("sample_text_out_list.txt", "w+", encoding="utf-8") as file: file.writelines(data)
【sample_text_out_list.txtの内容】 Python ファイルの入出力の基本 テキストファイルの入出力
上記のようにwritelinesでリストを指定するだけで簡単に文字列のリストをテキストファイルへ書き込むことができます。各文字列ごとに改行したい場合は、上記のように"\n"を含める必要があります。
バイナリファイルの入出力
画像などのバイナリファイルの読み込み、書き込みの例を紹介します。使用方法としては、基本的にテキストファイルの場合と同様です。
バイナリファイルの読み込み
ファイル内容をまとめて取得する read
バイナリファイル内容をまとめて取得する場合には、テキストファイルと同様にreadメソッドを使用します。
バイナリファイルを読み込む際には、mode引数の部分にバイナリを表すbを付けて、"rb"モードで読み込みを行います。
with open("sample_binary.png", "rb") as file: data = file.read() print(data)
【実行結果例】 b'\x89PNG\r\n\x1a\n\x00\x00\x00(・・・中略・・・)\xaeB`\x82'
ファイル内容を1バイトずつ取得する read(1)
バイナリファイルを1バイトずつ読み込みたい場合は、以下のようにread(1)として読み込むことができます。
with open("sample_binary.png", "rb") as file: data = [] while d := file.read(1): data.append(d) print(data, "\n") data_bin = b"".join(data) print(data_bin)
【実行結果】 [b'\x89', b'P', b'N', b'G', b'\r', b'\n', b'\x1a', b'\n', b'\x00', b'\x00', b'\x00',(・・・中略・・・), b'\xae', b'B', b'`', b'\x82'] b'\x89PNG\r\n\x1a\n\x00\x00\x00(・・・中略・・・)\xaeB`\x82'
上記のように1バイトずつリストに取得することが可能です。また、全体をつなげたい場合は、b"".join(data)のようにすることでつなげることもできます。
バイナリファイルへの書き込み
データをバイナリファイルへ書き込む write
バイナリファイルを書き込む場合には、writeメソッドを使用します。
バイナリファイルを書き込む際には、mode引数の部分にバイナリを表すbを付けて、"wb"モードで書き込みます。
with open("sample_binary.png", "rb") as file: data = file.read() # バイナリファイルの書き込み with open("sample_binary_out.png", "wb") as file: file.write(data)
上記はバイナリファイルを読み込んで別名でコピーしているような例ですが、このように簡単にバイナリファイルを出力することができます。
まとめ
Pythonでファイル入出力に関わる関数・メソッド(open, close, read, readlines, write, writelines)やwithについて解説しました。
ファイルの入出力の基本の流れは以下の通りで、各種関数やメソッドの使い方を例を使って紹介しました。
- open関数でファイルを開く
- 「readやreadlineメソッドでデータを読み込む」または「writeやwritelinesメソッドでデータを書き込む」といった入出力処理を実行する
- closeメソッドでファイルを閉じる
また、ファイルはclose忘れをすると問題がありますが、Pythonではwithをつかうことで必要な処理が終わったら自動でファイルをクローズすることができますのでしっかり活用しましょう。
ファイル入出力は、プログラミングの基本要素であるためうまく使いこなしてもらえたらなと思います。
上記で紹介しているソースコードについてはgithubにて公開しています。参考にしていただければと思います。