Python

【Python】ファイルの読み込みとファイルへの書き出し方法について学ぼう

ファイルの読み込みとファイルへの書き出し方法について学ぼう Python

前回の記事でPythonにおけるプログラム実行時の例外処理について学びました。

今回は、もう少し実用的なプログラミングということで、ファイル操作について学んでいきたいと思います。

実際にシステムをプログラミングする際には、ログの出力やファイル読み込みなどのファイル操作はよく使うので、覚えておくと非常に重宝すると思います。

ファイル操作が出来るようになると、作れるプログラムの幅もグッと広がりますね

この記事を読んで分かること
  • ファイル操作とは何かがわかる
  • Pythonでのファイルの読み込みや書き込みの方法がわかる
スポンサーリンク

ファイルのアクセスについて

ファイル操作に関して、ファイルへのアクセスする関数について説明します。

open関数でのファイルアクセス

ファイルへのアクセスはopen関数を使います。

with open(ファイルパス, mode=モード, encoding=エンコード)as 変数 :
    …ファイルアクセスの処理…

open関数は基本的に3つの引数を使って指定します。

  • 第1引数:アクセスするファイルのパスを文字列で指定
  • 第2引数:アクセスモードの指定、省略時は読み込みモード(”r”)
  • encoding(キーワード引数):ファイルの文字コードを指定、省略時は実行時のプラットフォームに依存

モードの指定、エンコードの指定方法は以下となります

モード役割
“r”読み込みするときに指定。
省略した場合は”r”でopenする。
“w”書き込みするときに指定。
ファイルが存在しない場合新しいファイルが作られる。
ファイルが存在する場合はファイルを上書き。
“x”書き込みするときに指定。
ファイルが存在しない場合のみファイルを作成し書き込む。
ファイルが存在する場合は何もしない。
“a”書き込みするときに指定。
ファイルが存在しない場合はファイルを作成し書き込む。
ファイルが存在する場合は末尾に書き込み。
エンコード役割
“utf_8”UTF-8(ユニコード)
“shift_jis”Shift_JIS(Windowsが標準の日本語文字コード)
“euc_jp”日本語EUC
“ascii”ASCII文字

それからopen関数の前に「with」とありますが、open関数を使う場合はwith構文とセットで覚えてしまいましょう。

open関数を使ってファイルにアクセスした場合に、必ずそのファイルをclose(クローズ処理)しなければなりません。
ですがクローズ処理は結構忘れますし、またファイルオープン後に例外が発生した場合にクローズ処理されないまま処理が中断してしまうこともあります。

ですがwith構文を使うと、with構文を抜けた際に自動的にファイルをクローズしてくれます。
例外が発生した場合でも同様に自動でクローズしてくれます

おー便利ですねぇ

なのでファイルアクセス時のopen関数を使う場合はもうwith構文はセットで覚えておきましょう。

ファイルのopen処理後に「as 変数」にファイルアクセス用の変数が格納されますので、その変数を使ってファイルのアクセスをします。

スポンサーリンク

ファイルの読み込み

では実際に上記open関数を使ってファイルの読み込みをしてみましょう。

まずは、実行ファイルと同じ場所に「sample.txt」という名前のファイルを作成します。

ファイルの内容は以下。

This is sample text file.
Hello!
Welcome.
Goodbye!
ohayou.
konnitiwa.
sayonara.
end.

とりあえず、今の段階では日本語は書かないでおきますね。
(文字コードに関しては後から説明しますので)

readで全てのテキストを読み込む

ファイルオブジェクトからテキストデータを読み込む場合は「read」メソッドを使います。

ファイルオブジェクト.read(サイズ)

readメソッドは引数を1つ取り、サイズを指定すると何文字分読み込むかを指定できます。
引数を省略するとファイル内の全てのデータを読み込みます

では実際にファイルを読み込んでみましょう。

with open("sample.txt") as fs:
    result = fs.read()
    print(result)

1行目で読み込むファイルを指定しています。
ファイルは同じディレクトリにあるのでパスは指定せずにファイル名のみ記述しています。
また引数でモード、エンコードの指定をしていないので、モードは読み込みモード、エンコードは環境依存となります。

そして2行目でアクセスしたファイルをreadメソッドで読み込み、3行目で出力しています。

またwith構文を使っていますので、ファイルクローズの処理も不要です。

実行すると以下となります。

This is sample text file.
Hello!
Welcome.
Goodbye!
ohayou.
konnitiwa.
sayonara.
end.

正しくファイルが読み込めて、ターミナル上に出力されていることが分かります。

1行ずつ読み込む

ファイルを読み込んで操作をする場合に、readを使えば非常に簡単にデータを一度で取得できる反面ファイルが膨大な量だった場合は読み込む処理に時間がかかったり、読み込むだけでメモリがいっぱいになったりなど問題点もあります。

なので、ファイルを1行単位で読み込んで操作をするというのが最も一般的なファイル操作となります。

ファイルを1行単位で読み込むにはファイルオブジェクトをfor文で取得すれば良いです。

では、先ほどのファイル操作の処理を1行単位に読み込むように変更してみましょう。

with open("sample.txt") as fs:
    for line in fs:
        result = line.strip()
        print(result)

2行目の処理でファイルを格納した変数「fs」をfor文でリスト形式として1行単位で取得しています。

そして3行目で「strip()」メソッドを呼び出していますが、これは各行の最後にある改行コードを削除しています。
これをしないと、各行の改行コードが残ったままprintでも改行されて出力されるため、出力時に1行空行されて表示されます。

こちらも実行すると先ほどの出力と全く同じになりますが、処理としては1行毎にデータを取得して出力します

This is sample text file.
Hello!
Welcome.
Goodbye!
ohayou.
konnitiwa.
sayonara.
end.

文字コードを指定してテキストを読み込む

文字コードを指定して読み込む場合を考えてみましょう。

例えばインターネット上のファイルを読み込む場合や、異なるプラットフォームでのファイルを読み込む場合は日本語などが含まれていると文字コードの関係で正しく読み込めない場合があります。

例えば、ユニコードのファイルをShift-JISで読み込むと以下のようなエラーが出ます。

UnicodeDecodeError: 'shift_jis' codec can't decode byte 0x81 in position 55: illegal multibyte sequence

その場合は、ファイルの文字コードを指定してファイルをopenします。

具体的にはキーワード引数「encoding=」にファイルにあわせたエンコードを指定します。

ここでは一般的なユニコードのファイルを指定してみましょう。

This is sample text file.
Hello!
Welcome.
Goodbye!
おはよう。
こんにちは。
さようなら。
end.

上記「sample.txt」をユニコード形式で保存します。

では、上記ファイルを読み込んで出力してみましょう。

with open("sample.txt",encoding="utf-8") as fs:
    for line in fs:
        result = line.strip()
        print(result)

1行目のファイル読み込み時のキーワード引数にユニコードを示す「encoding=”utf-8″」と指定しています。

これでファイルのフォーマットがユニコードであればファイル読み込みができます。

上記を実行してみると結果は以下となり、ユニコードのファイルが正しく読み込めていることが分かります。

This is sample text file.
Hello!
Welcome.
Goodbye!
おはよう。
こんにちは。
さようなら。
end.
スポンサーリンク

ファイルの書き込み

では続いてファイルへの書き出しをしてみましょう。

といってもファイルの書き出しも基本的な流れはファイル読み込みと同じです。

ただし、open関数でモードを指定する際に「w」「x」「a」のいずれかを指定します。
※モード指定の詳細に関しては上記「モード指定」を参照

ファイルへの書き出しとwriteメソッド

ファイルオブジェクトにデータを書き込む場合は「write」メソッドを使います。

ファイルオブジェクト.write(書き込む文字列)

引数にはファイルに書き出す値を文字列で指定します。これで指定した文字列がそのままファイルに書き出されます
ちなみにwriteは戻り値として、書き出した文字列のサイズ(文字数)を整数値で返しますが、特に必要なければ受け取らなくて大丈夫です。

では実際にファイルに書き込んでみましょう。

msg = input("テキストに入力するデータ:")

with open("sample_write.txt","w") as fs:
    fs.write(msg)
    print("書き込みました")

入力した値を「sample_write.txt」ファイルに出力します。

今回は書き込みですので、モードを書き込みの「w」で指定しています。
そしてファイル変数のwriteメソッドを使ってファイルに書き出しています。

実行すると以下となります。

テキストに入力するデータ:こんにちは
書き込みました

出力されたファイルをみると「こんにちは」と出力されています。

こんにちは

連続で書き込む

では、ファイルをopen中に連続でwriteメソッドを呼び出すとどうなるでしょうか。

writeメソッドを連続して呼び出すと、前回書き出した値の後に新しい値を追記します

with open("sample_write.txt","w") as fs:
    while True:
        msg = input("テキストに入力するデータ:")
        if msg == "":
            break
        fs.write(msg)
    print("書き込みました")

上記のプログラムは、入力されたデータを繰り返し書き込む処理です。

これを実行してみましょう。

テキストに入力するデータ:こんにちは
テキストに入力するデータ:こんばんは
テキストに入力するデータ:はじめまして
テキストに入力するデータ:おはよう
テキストに入力するデータ:
書き込みました

そうすると、ファイルでは入力された文字列が改行なしに連続で追記されています。

こんにちはこんばんははじめましておはよう

ちなみに1行毎に改行を入れて書き込みたい場合は、writeに書き込む文字列に改行コードの「\n」を明示的に入れます

with open("sample_write.txt","w") as fs:
    while True:
        msg = input("テキストに入力するデータ:")
        if msg == "":
            break
        fs.write(msg+"\n")
    print("書き込みました")

6行目のwriteの文字列の最後に「\n」の改行コードを入れています。

先ほどと同様に実行すると、ファイル内できちんと改行されていることが分かります。

こんにちは
こんばんは
はじめまして
おはよう

文字コードを指定してテキストに書き込む

では、文字コードを指定してファイルに書き込んでみましょう。

こちらも読み込み時と同様にopen関数の際のキーワード引数「encoding」に、文字コードを指定すれば良いです。

with open("sample_write.txt","w",encoding="utf-8") as fs:
    while True:
        msg = input("テキストに入力するデータ:")
        if msg == "":
            break
        fs.write(msg+"\n")
    print("書き込みました")

上記で文字コードに「encoding=”utf-8″」を指定していますので、テキストファイルはユニコードで保存されます。

スポンサーリンク

ファイルアクセスの例外処理

ファイル操作ですが、ファイルアクセス中にさまざまな要因で例外が発生します。

下記はファイル操作中に起こる例外の一例です。

エラー名内容
ValueErrorアクセス時に既にファイルがcloseされていた場合
FileNotFoundError読み込み(r)モードでopenした時にファイルが見つからない場合
FileExistsError排他的生成(x)モードでopenした時に既に同名ファイルが存在する場合
PermissionErrorアクセスするファイルがOSによりパーミッションが与えられてない場合
io.UnsupportedOperation読み込みモードで開いているファイルに書き出すなどサポート外の操作をした場合

ですので、ファイル操作の処理を書く際は例外処理も合わせて記述することをお勧めします。

例外処理を行う

では、ファイルの書き込みに例外処理を入れてみましょう。

try:
    with open("sample_write.txt","w",encoding="utf-8") as fs:
        msg = input("テキストに入力するデータ:")
        fs.write(msg)
        print("書き込みました")

except Exception as err:
    print("[ERROR]:"+str(err))

try内で起こる例外を「expert Exception」でキャッチしています。
これでファイルアクセス時に予期せぬエラーが発生してもプログラムが中断することなく処理が継続できます。

また必要に応じて、例外の種類毎に例外処理を追加すると良いでしょう。

では実行してみましょう。

上記で「w」を「r」に変更して実行すると書き込みエラー「x」に変更して実行するとファイルが存在するためエラーが例外処理として表示されます。

テキストに入力するデータ:a
[ERROR]:not writable

[ERROR]:[Errno 17] File exists: 'sample_write.txt'
スポンサーリンク

まとめ

今回は、Pythonでのファイル操作について学びました。