2.27. 読み書き

ファイルはディスク上に存在します。Python は open() を通じてそれらにアクセスし、この関数は、メソッドが基盤となるバイトを読み書きするファイルオブジェクトを返します。

2.27.1. open とモード

最初の引数はパス、2番目はモードです。モードは、ファイルがどのように使われるかを Python に伝える短い文字列です:

  • "r" -- 読み込み(デフォルト)。既存のファイルを読み込み用に開きます。

  • "w" -- 書き込み。新しいファイルを作成するか、既存のファイルを空に切り詰めます。

  • "a" -- 追記。切り詰めずに、ファイルをその末尾での書き込み用に開きます。

  • 上記のいずれかに "b" を付けたもの("rb""wb""ab")-- バイナリモード。ファイルの内容は str ではなく bytes になります。

f = open("notes.txt", "r")
text = f.read()
f.close()

2.27.2. コンテキストマネージャを使う

上記のパターンは、open()close の間で何かが例外を送出すると、ファイルハンドルを漏らします。その解決策が with 文です(コンテキストマネージャ を参照):

with open("notes.txt") as f:
    text = f.read()

# f is closed here, even if read() failed

これが標準的な形です。毎回このように書きましょう。

2.27.3. 読み込み

ファイルオブジェクトはいくつかの読み込みスタイルをサポートします:

  • io.IOBase.read() -- ファイル全体(または N バイト)を読み込み、単一の文字列(または bytes オブジェクト)として返します。

  • io.IOBase.readline() -- 末尾の "\n" を含めて1行を読み込みます。

  • ファイルを直接反復すると、1行ずつ得られ、ファイル全体を一度に読み込むよりもはるかに少ないメモリで済みます。

with open("log.txt") as f:
    for line in f:
        print(line.rstrip())

str.rstrip() は出力が二重に行間が空かないように、表示前に末尾の改行を取り除きます。

2.27.4. 書き込み

"w" モードでファイルを開き、io.IOBase.write() を使います:

with open("out.txt", "w") as f:
    f.write("hello\n")
    f.write("world\n")

io.IOBase.write() は改行を追加しません。与えたバイト(テキストモードでは文字)を正確に書き込みます。

2.27.5. テキスト対バイナリ

テキストモード(デフォルト、"b" なしの "r" / "w")は、入ってくるバイトをデフォルトのエンコーディングで str にデコードし、出ていく str をバイトに戻してエンコードします。設定、ログ、JSON など、テキストであるものに使います。

バイナリモード("rb" / "wb")はデコードのステップを省き、bytes を返します。画像、struct でパックされたレコード、ネットワークキャプチャなど、すべてのバイトが重要でファイルが人が読めるものではない場合に使います。

2.27.6. ファイルの一覧表示と削除

os モジュールは、ファイルオブジェクト自身にはないファイルシステム操作を公開します:

  • os.listdir() -- ディレクトリ内の名前のリストを返します。

  • os.remove() -- ファイルを削除します。

  • os.rename() -- ファイルの名前を変更します。

  • os.stat() -- ファイルのメタデータ(サイズ、変更時刻など)。

  • os.mkdir() -- 新しいディレクトリを作成します。

import os

for name in os.listdir("/"):
    print(name)

ファイルやディレクトリが存在しない可能性がある場合は、これらの周りで OSError を捕捉してください。この操作は、実際のスクリプトで例外が現れる一般的な場所の1つです。