[Pythonのはじめ方] Part14: ファイルの読み書き(open, with)

プログラミングでは、ファイルにデータを保存したり、ファイルからデータを読み込んだりする操作が頻繁に必要になります。Pythonでは、組み込み関数 open() を使って簡単にファイル操作を行うことができます。このステップでは、ファイルの基本的な読み書き方法と、より安全にファイルを扱うための with 文について学びましょう!

1. ファイルを開く: open() 関数

ファイル操作の第一歩は、対象のファイルを開くことです。これには open() 関数を使います。基本的な構文は以下の通りです。

f = open('ファイル名', 'モード', encoding='文字コード')
  • ファイル名: 操作したいファイルの名前(パスを含むことも可能)を指定します。例: 'my_file.txt', 'data/log.csv'
  • モード: ファイルをどのように開くかを指定します。主なモードには次のようなものがあります。省略すると 'r' (読み込みモード)になります。
  • encoding: ファイルの文字コードを指定します。テキストファイルを扱う場合、特に日本語などASCII文字以外を含む場合は、'utf-8' を指定するのが一般的です。指定しない場合、OSのデフォルト設定に依存し、意図しないエラー(文字化けなど)が発生することがあります。

主なファイルモード

open() 関数の第二引数で指定するモードは、ファイル操作の種類を決定します。

モード 説明 ファイルが存在しない場合 ファイルが存在する場合
'r' 読み込み専用 (Read)。デフォルト。 エラー (FileNotFoundError) ファイルの内容を読み込む。
'w' 書き込み専用 (Write)。 新規作成 既存の内容を上書き 덮어쓰기
'a' 追記専用 (Append)。 新規作成 ファイルの末尾に追記する。
'x' 排他的書き込み (Exclusive creation)。 新規作成 エラー (FileExistsError)
'b' バイナリモード。画像や音声などテキスト以外のファイル用。'rb', 'wb', 'ab' のように他のモードと組み合わせて使う。
'+' 読み書き両用モード。'r+', 'w+', 'a+' のように他のモードと組み合わせて使う。
注意: 'w' モードは、ファイルが既に存在する場合、確認なしに内容を完全に消去して上書きします。大切なファイルを誤って消さないように注意しましょう!

2. ファイルからの読み込み

ファイルを開いたら ('r' モードなど)、内容を読み込むことができます。いくつかの方法があります。

read(): ファイル全体を読み込む

ファイルの内容全体を一つの文字列として読み込みます。

# sample.txt というファイルを用意しておく
# 内容:
# Hello, Python!
# This is a sample file.

f = open('sample.txt', 'r', encoding='utf-8')
content = f.read()
print(content)
# 出力:
# Hello, Python!
# This is a sample file.

f.close() # ファイルを閉じるのを忘れずに!

readline(): 1行ずつ読み込む

ファイルを1行ずつ読み込みます。呼び出すたびに次の行を返し、ファイルの終わりに達すると空文字列 '' を返します。

f = open('sample.txt', 'r', encoding='utf-8')
line1 = f.readline()
print(f"1行目: {line1.strip()}") # strip()で末尾の改行コードを削除
line2 = f.readline()
print(f"2行目: {line2.strip()}")
line3 = f.readline() # ファイルの終端を超えると空文字列
print(f"3行目: {line3}")

f.close()
# 出力:
# 1行目: Hello, Python!
# 2行目: This is a sample file.
# 3行目:

readlines(): 全行をリストとして読み込む

ファイルのすべての行を読み込み、各行を要素とするリストを返します。各要素(行)の末尾には改行文字 \n が含まれる点に注意が必要です。

f = open('sample.txt', 'r', encoding='utf-8')
lines = f.readlines()
print(lines)
# 出力: ['Hello, Python!\n', 'This is a sample file.\n']

# 各行を表示 (改行コードを除去)
for line in lines:
    print(line.strip())

f.close()
# 出力:
# Hello, Python!
# This is a sample file.

forループで1行ずつ読み込む (推奨)

ファイルオブジェクトはイテレータでもあるため、forループで直接1行ずつ処理するのがメモリ効率も良く、簡潔で推奨される方法です。

f = open('sample.txt', 'r', encoding='utf-8')
for line in f:
    print(line.strip()) # 1行ずつ処理
f.close()
# 出力:
# Hello, Python!
# This is a sample file.

3. ファイルへの書き込み

ファイルにデータを書き込むには、'w' (上書き) または 'a' (追記) モードでファイルを開きます。

write(): 文字列を書き込む

指定した文字列をファイルに書き込みます。改行は自動的に挿入されないため、必要であれば改行文字 \n を自分で含める必要があります。

# new_file.txt を 'w' モードで開く (存在すれば上書き)
f = open('new_file.txt', 'w', encoding='utf-8')

f.write('これは最初の行です。\n') # \n で改行
f.write('This is the second line.')
f.write(' まだ2行目です。')

f.close() # 書き込み後も必ず閉じる

# new_file.txt の内容:
# これは最初の行です。
# This is the second line. まだ2行目です。

writelines(): 文字列のリストを書き込む

文字列のリスト(やタプルなど)を受け取り、各要素を連結してファイルに書き込みます。write() と同様に、改行は自動的に挿入されません。

lines_to_write = [
    'リストの1行目\n',
    'リストの2行目\n',
    'リストの3行目'
]

# append_file.txt を 'a' モードで開く (追記)
f = open('append_file.txt', 'a', encoding='utf-8') # 追記モード

f.writelines(lines_to_write)

f.close()

# append_file.txt に lines_to_write の内容が追記される
ヒント: write()writelines() は、書き込んだ文字数(バイト数ではない)を返しますが、通常はこの戻り値を使うことは少ないです。

4. ファイルを確実に閉じる: with 文 (推奨)

open() でファイルを開いた後は、必ず close() メソッドを呼び出してファイルを閉じる必要があります。ファイルを閉じないと、以下のような問題が発生する可能性があります。

  • 書き込み内容がファイルに完全に反映されないことがある(バッファリングのため)。
  • OSが同時に開けるファイル数には制限があり、リソースを無駄に消費する。
  • 他のプログラムがそのファイルにアクセスできなくなることがある。

しかし、プログラムの途中でエラーが発生した場合など、close() が実行されない可能性もあります。そこで、より安全かつ確実にファイルを閉じるために with を使うことが強く推奨されます。

# with文を使ったファイルの読み込み
try:
    with open('sample.txt', 'r', encoding='utf-8') as f:
        # このブロック内でファイル操作を行う
        content = f.read()
        print("--- with文での読み込み ---")
        print(content)
    # withブロックを抜けると、ファイルは自動的に閉じられる! f.close() は不要

except FileNotFoundError:
    print("エラー: sample.txt が見つかりません。")


# with文を使ったファイルの書き込み
lines_for_with = ["with文で書き込み 1行目\n", "with文で書き込み 2行目\n"]
try:
    with open('with_output.txt', 'w', encoding='utf-8') as f:
        f.writelines(lines_for_with)
        print("--- with文での書き込み完了 ---")
    # ブロックを抜けると自動的に close される

except IOError:
    print("エラー: ファイルへの書き込み中に問題が発生しました。")

ポイント: with 文を使うと、ブロック内の処理が正常に終了した場合でも、途中でエラーが発生した場合でも、必ずファイルが自動的に閉じられます。これにより、close() の呼び忘れを防ぎ、より安全で簡潔なコードを書くことができます。ファイル操作では、可能な限り with 文を使用しましょう!

5. 文字コード (Encoding) について

テキストファイルを扱う際、文字コード(エンコーディング)は非常に重要です。文字コードとは、文字をコンピュータが理解できるバイト列に変換するためのルールです。

  • 日本語を含むファイルを扱う場合は、encoding='utf-8' を指定するのが一般的で、最も推奨されます。
  • Windows環境では、古いファイルなどで 'cp932' (または 'shift_jis') が使われていることもあります。
  • open()encoding を指定しないと、PythonはOSのデフォルト設定を使おうとします。これがファイルの実際の文字コードと異なると、UnicodeDecodeError (読み込み時) や UnicodeEncodeError (書き込み時) が発生したり、文字化けの原因になったりします。

ファイルを読み書きする際は、対象ファイルの文字コードを把握し、open() 関数で適切に encoding を指定する習慣をつけましょう。

# UTF-8 でファイルを書き込む例
try:
    with open('japanese_utf8.txt', 'w', encoding='utf-8') as f:
        f.write('これはUTF-8で保存されたファイルです。\n')

    # UTF-8 でファイルを読み込む例
    with open('japanese_utf8.txt', 'r', encoding='utf-8') as f:
        content = f.read()
        print(content)

except IOError as e:
    print(f"ファイル操作エラー: {e}")
except Exception as e:
    print(f"予期せぬエラー: {e}")

まとめ

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

  • ファイル操作の基本は open() 関数。モードと文字コードの指定が重要。
  • 読み込みには read(), readline(), readlines() があるが、for ループでの反復処理が効率的。
  • 書き込みには write(), writelines() を使う。改行 \n は自分で追加する必要がある。
  • ファイルの閉じ忘れを防ぐため、with 文を使うのがベストプラクティス
  • 文字コード (encoding) を意識し、特に日本語を扱う際は 'utf-8' を指定する。

ファイル操作は、データを永続化するための基本スキルです。テキストファイルだけでなく、次のステップで学ぶJSONファイルなど、様々な形式のデータを扱えるようになりましょう!

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です