中間ファイルの寿命をwithで区切る
画像変換や集計の途中で作った作業ファイルが毎回残るなら、TemporaryDirectoryを使い、処理の期間だけ存在する専用フォルダーへまとめるとよい。withブロックを抜けると、その中のファイルとフォルダーが片付けられる。正常終了だけでなく、通常の例外でブロックを抜けたときも後始末の対象になる。
重要なのは、残す成果物と消してよい中間物を分けることである。一時フォルダーの中に最終結果を作ったままパスだけ返しても、ブロック終了後にはそのパスは使えない。必要な結果はメモリ上の値として返すか、withを抜ける前に別の保存先へ書き出す。以下では実データに触れないよう、最終結果の保存先も外側の一時領域へ作る。
正常終了と例外時の両方を確認する
example.py
from pathlib import Path
from tempfile import TemporaryDirectory
with TemporaryDirectory() as sandbox:
output = Path(sandbox) / "result.txt"
with TemporaryDirectory(prefix="convert-", dir=sandbox) as work:
work_path = Path(work)
intermediate = work_path / "intermediate.txt"
intermediate.write_text("alpha\nbeta\n", encoding="utf-8")
with intermediate.open(encoding="utf-8") as stream:
result = stream.read().upper()
output.write_text(result, encoding="utf-8")
assert intermediate.exists()
assert not work_path.exists()
assert output.read_text(encoding="utf-8") == "ALPHA\nBETA\n"
print("normal cleanup:", not work_path.exists())
print("result:", output.read_text(encoding="utf-8").splitlines())
try:
with TemporaryDirectory(prefix="failed-", dir=sandbox) as work:
failed_path = Path(work)
(failed_path / "partial.txt").write_text("partial", encoding="utf-8")
raise RuntimeError("simulated conversion failure")
except RuntimeError:
assert not failed_path.exists()
print("exception cleanup:", not failed_path.exists())
実行結果
normal cleanup: True
result: ['ALPHA', 'BETA']
exception cleanup: True
ファイルを先に閉じる理由
内側のファイルを開く処理にもwithを使っている。ファイルのwithが先に終わり、その後でディレクトリのwithが終わるため、開いたままのファイルを削除しようとする状況を避けやすい。Windowsなどでは開いているファイルの削除が拒否される場合がある。Linuxで削除できたから、すべてのOSで同じように動くとは限らない。
TemporaryDirectoryが返すのはフォルダー名の文字列なので、Path(work)へ変換すると中のパスを組み立てやすい。prefixは人が調べたときに用途を分かりやすくするための接頭辞である。実際の名前は自動生成されるため、固定名の作業フォルダーを複数の処理で取り合うことを減らせる。
dirを指定しない場合はシステム側の一時領域が使われる。大きな中間ファイルを扱うなら、その保存先に十分な空き容量があるか、メモリ上のファイルシステムではないかなどを確認する。例ではsandboxを指定し、作成するすべてのファイルを管理された一つの領域へ収めている。
片付けられる場合と、保証できない場合
例のRuntimeErrorは、後始末を確認するために意図的に発生させた例外である。外側のexceptで捕まえる時点では一時フォルダーが消えていることをassertしている。ただし、プロセスの強制終了、OSの停止、停電ではPythonの後始末が実行されない場合がある。TemporaryDirectoryはどんな終了方法でも必ず痕跡が残らない機能ではない。
削除する権限が変わったり、別のプロセスがファイルを使用していたりすれば、後始末そのものが失敗することもある。失敗を無条件に無視すると、一時ファイルが残っていることに気づきにくくなる。例では既定の動作を使い、後始末の失敗を隠す設定は加えていない。実運用では残った場所が分かる記録を用意すると調査しやすい。
一時ディレクトリは暗号化された保管庫ではない。消去は通常のファイル削除であり、媒体上のデータの完全な消去を保証するものでもない。機密データを一時的に保存する場合は、権限、保存先、バックアップや同期の対象かを確認する。必要のない個人情報を中間ファイルへ出さない設計も重要である。
例外を残しながらデバッグする
失敗時の中間データを調べたい場合でも、一時フォルダーを永久に残す変更をそのまま通常運用へ持ち込まない。必要なログや小さな診断結果だけを、明示した保存先へコピーしてから例外を伝える方法がある。残す情報と消す情報の境界を決めれば、片付けと調査を両立しやすい。
返り値に一時パスを含める設計では、そのパスを使える期間を呼び出し側へ伝える必要がある。関数の外で使うファイルなら、呼び出し側が一時領域のwithを管理する形へ変えると寿命が明確になる。資源を作る場所と、その資源を使い終える場所を同じ階層で管理するのが基本になる。
実行環境と関連情報
掲載コードはLinux上のCPython 3.12.14で実行した。OS固有のファイル操作や対話環境の違いは、本文に記した条件に従って扱う。
関連:保存途中で元ファイルを壊さない:一時ファイルから置き換える / fixtureとtmp_pathで実データを壊さずファイル処理をテストする
- Python公式ドキュメント(2026年10月2日参照)
