Python 入門

Python ファイル書き込み

データのファイル書き込みは、プログラミングにおける非常に基礎的な操作であり、情報を永続的に保存することを可能にします。

前章では、ファイルを読み込むための様々なモードについて学習しました。
本章では、ファイルへのデータ書き込みに焦点を当てます。これには、書き込みを許可するモードでファイルをオープンし、Pythonを使用してデータをインサート(挿入)する作業が含まれます。

ここでは、各書き込みモードの違いや、データが正しく保存されることを保証するためのファイルクローズ処理について解説します。

1. ファイル書き込み:モードと操作

ファイルにデータを書き込むには、いずれかの書き込みモードでファイルをオープンする必要があります。最も一般的に使用されるモードは以下の通りです。

  • 'w'(書き込み - Write): ファイルを書き込み用にオープンします。ファイルが既に存在する場合、その内容は上書き(オーバーライト)されます。ファイルが存在しない場合は、新規ファイルが作成されます。
  • 'a'(追記 - Append): ファイルを追記用にオープンします。ファイルが既に存在する場合、新しいデータはファイルの末尾に追加されます。ファイルが存在しない場合は、新規ファイルが作成されます。
  • 'x'(排他的作成 - Exclusive Creation): 新規作成専用でオープンします。ファイルが既に存在する場合、この操作は失敗し FileExistsError をスローします。

1.1 'w'(書き込み)モードの使用

'w' モードは、新しいファイルを作成するか、既存のファイルを上書きするために使用します。このモードを使用すると、ファイル内に存在する既存のデータがすべて消去されるため、使用には十分な注意が必要です。

# 例:'w' モードでファイルにデータを書き込む
try:
    with open('my_file.txt', 'w') as file:
        file.write('これは1行目です。\n')
        file.write('これは2行目です。\n')
    print("データが my_file.txt に正常に書き込まれました。")
except Exception as e:
    print(f"エラーが発生しました:{e}")

# ファイル内容の確認:
# my_file.txt には以下が含まれます:
# これが1行目です。
# これが2行目です。

この例では、with open() 構文(コンテキストマネージャ)を使用して、書き込み後にファイルが正しくクローズされることを保証しています。file.write() メソッドは指定された文字列をファイルに書き込み、\n 文字は改行を挿入して、各内容が独立した行に記述されるようにします。

1.2 'a'(追記)モードの使用

'a' モードは、既存ファイルの末尾にデータを追加するために使用します。ファイルが存在しない場合は新規作成されます。これは、ログの記録や、既存の内容を保持したままデータを追加したい場合に非常に有用です。

# 例:'a' モードでファイルにデータを追記する
try:
    with open('my_file.txt', 'a') as file:
        file.write('これは3行目(追記された内容)です。\n')
    print("データが my_file.txt に正常に追記されました。")
except Exception as e:
    print(f"エラーが発生しました:{e}")

# ファイル内容の確認:
# my_file.txt には現在、以下が含まれています:
# これが1行目です。
# これが2行目です。
# これは3行目(追記された内容)です。

この例では、新しい行が既存の内容の後に追加されています。もし my_file.txt が事前に存在しなかった場合、システムによって自動的に作成されます。

1.3 'x'(排他的作成)モードの使用

'x' モードは新しいファイルを作成するために使用されますが、そのファイルがまだ存在しない場合のみ有効です。ファイルが既に存在する場合は FileExistsError が発生します。既存のファイルを誤って上書きしたくない場合に非常に便利なモードです。

# 例:'x' モードを使用して新規ファイルを作成する
try:
    with open('new_file.txt', 'x') as file:
        file.write('これは新規ファイル内の最初の行です。\n')
    print("new_file.txt が作成され、データが正常に書き込まれました。")
except FileExistsError:
    print("エラー:new_file.txt は既に存在します。")
except Exception as e:
    print(f"エラーが発生しました:{e}")

もし new_file.txt が既に存在する場合、プログラムは「エラー:new_file.txt は既に存在します。」と出力します。存在しない場合は、ファイルが作成され内容が書き込まれます。

2. 異なるデータ型の書き込み

file.write() メソッドは、入力として文字列(String)のみを受け付けます。整数(Integer)、浮動小数点数(Float)、リスト(List)などの他のデータ型を書き込みたい場合は、まずそれらを文字列に変換する必要があります。

2.1 数値の書き込み

数値をファイルに書き込むには、str() 関数を使用して文字列にキャスト(変換)します。

# 例:数値をファイルに書き込む
try:
    with open('numbers.txt', 'w') as file:
        number1 = 10
        number2 = 3.14
        file.write(str(number1) + '\n')
        file.write(str(number2) + '\n')
    print("数値が numbers.txt に正常に書き込まれました。")
except Exception as e:
    print(f"エラーが発生しました:{e}")

# ファイル内容の確認:
# numbers.txt には以下が含まれます:
# 10
# 3.14

この例では、str(number1)str(number2) を使用して、整数 10 と浮動小数点数 3.14 を書き込む前に文字列へ変換しています。

2.2 リストやタプルの書き込み

リストやタプルを書き込むには、要素を反復処理(イテレート)し、各要素を文字列に変換して連結します。

# 例:リストをファイルに書き込む
try:
    my_list = ['りんご', 'バナナ', 'さくらんぼ']
    with open('fruits.txt', 'w') as file:
        for fruit in my_list:
            file.write(fruit + '\n')
    print("リストが fruits.txt に正常に書き込まれました。")
except Exception as e:
    print(f"エラーが発生しました:{e}")

# ファイル内容の確認:
# fruits.txt には以下が含まれます:
# りんご
# バナナ
# さくらんぼ

2.3 辞書の書き込み

辞書を書き込む際は、後で読み戻しやすい形式にフォーマットするのが一般的です。一つの方法は、各キーと値を特定のルールで文字列化することです(より高度な手法としては JSON 形式がありますが、それは後のモジュールで扱います)。

# 例:辞書をファイルに書き込む(簡易版)
try:
    my_dict = {'名前': 'Alice', '年齢': 30, '都市': 'ニューヨーク'}
    with open('person.txt', 'w') as file:
        for key, value in my_dict.items():
            file.write(f'{key}: {value}\n')
    print("辞書が person.txt に正常に書き込まれました。")
except Exception as e:
    print(f"エラーが発生しました:{e}")

# ファイル内容の確認:
# person.txt には以下が含まれます:
# 名前: Alice
# 年齢: 30
# 都市: ニューヨーク

この例では、辞書をループで回し、各キー・バリューペアをコロンで区切って書き込んでいます。

3. ファイルのクローズ処理

書き込み完了後にファイルを正しくクローズすることは極めて重要です。これにより、すべてのデータが確実にディスクへ書き込まれ、システムリソースが解放されます。with open() 構文を使用すると、エラーが発生した場合でも自動的にクローズ処理が行われます。with 構文を使用しない場合は、file.close() メソッドを手動で呼び出す必要があります。

3.1 with open() の使用(推奨)

with open() 構文は、例外の発生に関わらず自動的にファイルをクローズするため、ファイル操作におけるベストプラクティスです。

# 例:'with open()' を使用した自動クローズ
try:
    with open('example.txt', 'w') as file:
        file.write('これは1行のテキストです。')
    print("データが example.txt に書き込まれ、ファイルは自動的にクローズされました。")
except Exception as e:
    print(f"エラーが発生しました:{e}")

3.2 手動でのファイルクローズ

with open() を使用しない場合は、必ず file.close() を呼び出さなければなりません。

# 例:手動でのファイルクローズ
import io

try:
    file = open('example.txt', 'w')
    file.write('これは1行のテキストです。')
    file.close()  # 手動でクローズ
    print("データが example.txt に書き込まれ、ファイルは手動でクローズされました。")
except Exception as e:
    print(f"エラーが発生しました:{e}")
finally:
    # エラーの有無に関わらず、確実にクローズされるようにする
    if 'file' in locals() and isinstance(file, io.IOBase) and not file.closed:
        file.close()

重要な注意点:

  • データ損失やリソースリークを防ぐため、特に書き込み後は必ずファイルが閉じられていることを確認してください。
  • 自動的かつ安全にクローズ処理を行う with open() 構文の使用を強く推奨します。

4. プログラミング実戦演習

1. ユーザーの入力を受け取り、それを user_input.txt というファイルに書き込むプログラムを作成してください。ユーザーの各入力は、独立した行として保存されるようにします。

try:
    with open('user_input.txt', 'w') as file:
        while True:
            line = input("テキストを入力してください('done' で終了):")
            if line.lower() == 'done':
                break
            file.write(line + '\n')
    print("データが user_input.txt に正常に書き込まれました。")
except Exception as e:
    print(f"エラーが発生しました:{e}")

2. ユーザーから名前のリストを読み取り、それらを names.txt というファイルに追記するプログラムを作成してください。ファイルが存在しない場合は、自動的に作成されるようにします。

try:
    with open('names.txt', 'a') as file:
        while True:
            name = input("名前を入力してください('done' で終了):")
            if name.lower() == 'done':
                break
            file.write(name + '\n')
    print("名前が names.txt に正常に追記されました。")
except Exception as e:
    print(f"エラーが発生しました:{e}")

3. 1から100までの数値を numbers.txt というファイルに書き込むプログラムを作成してください。各数値は1行ずつ保存されるようにします。

try:
    with open('numbers.txt', 'w') as file:
        for i in range(1, 101):
            file.write(str(i) + '\n')
    print("数値が numbers.txt に正常に書き込まれました。")
except Exception as e:
    print(f"エラーが発生しました:{e}")