Q1次のうち、フォルダごと再帰的に削除 したいときに使うのはどれですか?
shutil と tempfile — ファイル一括操作と一時ファイル
Python の shutil と tempfile を基礎から解説します。shutil.copy / shutil.move / shutil.rmtree によるファイル一括操作と、tempfile.NamedTemporaryFile による一時ファイルの安全な使い方を、ハンズオンで学べます。
ファイルとフォルダを丸ごと操作する shutil と、使い捨ての一時ファイル を扱う tempfile の 2 つを整理します。shutil.copy / move / rmtree によるファイル一括操作、NamedTemporaryFile の安全な使い方、両者を組み合わせたアトミック書き込みパターンまで扱います。
shutil — ファイルとフォルダの操作を 1 行で書く
shutil は shell utilities の略で、シェル(コマンドライン)で cp / mv / rm -r のように使う操作を Python のコードから 1 行で呼び出せる 標準ライブラリです。os モジュールにも os.rename などはありますが、shutil は 再帰的なフォルダコピー や ツリー削除 といった、よりまとまった単位の操作を提供します。
| 関数 | 動作 | 備考 |
|---|---|---|
| shutil.copy(src, dst) | ファイルを複製する | dst がフォルダなら同名でその中に作る |
| shutil.copy2(src, dst) | copy + 更新日時などのメタ情報も保持 | バックアップ用途に向く |
| shutil.copytree(src, dst) | フォルダごと再帰的に複製する | dst は **存在してはいけない** |
| shutil.move(src, dst) | ファイルやフォルダを移動・名前変更する | 同じパス上なら rename と等価 |
| shutil.rmtree(path) | フォルダと配下を再帰的に削除する | 戻せない。実行前に対象パスをよく確認する |
import shutil
import os
# 1) ファイルを別の場所にコピー (バックアップを作る典型例)
os.makedirs("backups", exist_ok=True) # コピー先のフォルダを用意
shutil.copy("data/sales.csv", "backups/sales_2024.csv")
shutil.move("logs/temp.log", "logs/archive_2024.log")
shutil.rmtree("old_data")
rmtree は取り消せない
shutil.rmtree(path) は path 配下を 物理削除 します。Python では「ゴミ箱」を経由せず、即座に消えます。実プロジェクトで使うときは消す対象を print で確認する、if path.startswith("/tmp") のようなガードを入れる など、人間と機械の両方で守る慣習を付けましょう。
tempfile — 安全に使い捨てファイルを作る
tempfile は 使い終わったら自動で消える一時ファイル を作るための標準ライブラリです。中間結果の保存・大量データの一時バッファ・テストの作業フォルダなど、「処理中だけ存在すれば良いファイル」のために使います。
手で tmp_xxx.txt のようなファイル名を考えると 他のプロセスとぶつかったり消し忘れたり しがちですが、tempfile は OS の一時フォルダ に 重複しないファイル名 で作り、処理が終わったら自動で消してくれます。
with ブロックに入った瞬間にファイルが作られ、ブロックを抜けるときに 自動で削除 される。ファイル名はその場で衝突しない名前が割り当てられるので、自分で命名する必要がない。| 関数・属性 | 意味 | 備考 |
|---|---|---|
| tempfile.NamedTemporaryFile | with で開閉する一時ファイル | delete=False で抜けても残す |
| tempfile.mkdtemp() | 一時フォルダのパスを返す | 削除は自分で shutil.rmtree |
| tempfile.gettempdir() | OS の一時フォルダのパスを返す | Linux なら /tmp、macOS は別パス |
| tf.name | 実ファイルパス(ランダム名) | with の中で参照できる |
| tf.write / tf.read | ファイルオブジェクトと同じ API | mode 引数で 'w' / 'r' / 'w+' を選ぶ |
import tempfile
import os
# with で安全に作って自動削除
with tempfile.NamedTemporaryFile(mode="w+", suffix=".txt", delete=True) as tf:
tf.write("集計結果の中間データ\n")
tf.seek(0)
print("中身:", tf.read())
print("パス:", tf.name)
# ← ここでブロックを抜けて自動削除される
delete=False と with を組み合わせる場面
書いてから別の場所で読み戻したい ときは delete=False を指定して、with を抜けてもファイルが残るようにします。残したファイルは 使い終わったら自分で os.remove(path) する か、後述のアトミック書き込みのように shutil.move で本来の保存先に置き換えます。
`delete=True` で自動削除される一時ファイル
重要な設定ファイルや状態ファイルを直接 open("settings.json", "w") で書き換えると、書き込み途中でプロセスが落ちたとき にファイルが半分書かれた状態で残ってしまい、次回読み込み時にパースエラーになります。これを避ける定石が 「一時ファイルに書ききってから、本来の場所に rename / move する」 という アトミック書き込み(atomic、途中で中断されても「完了したか / していないか」しか観測できない更新方式)パターンです。
import tempfile
import shutil
import json
final_path = "settings.json"
new_settings = {"theme": "dark", "lang": "ja", "fontSize": 14}
# 1) 一時ファイルに書き切る
with tempfile.NamedTemporaryFile(mode="w", delete=False, suffix=".json") as tf:
json.dump(new_settings, tf)
temp_path = tf.name
# 2) 完了したら本物のパスに移動 (この瞬間だけが「切り替わり」のタイミング)
shutil.move(temp_path, final_path)
# 3) 確認
with open(final_path) as f:
print(json.load(f))
# → {'theme': 'dark', 'lang': 'ja', 'fontSize': 14}
ファイルオブジェクトには 「現在の読み書き位置(カーソル)」 があり、`tf.write(...)` を呼ぶとカーソルは書いた直後の位置(= 末尾)に移動します。そのまま tf.read() を呼ぶと カーソルから後ろに何も無い ため空文字が返るので、`tf.seek(0)` でカーソルを先頭に戻してから 読み直す、というのが定石です。
mode="w+" は読み書き両用のモード
`mode="w+"` は 書き込みと読み込みを同じファイルハンドルで両方できる モードです。"w" だけだと書き込み専用で read() が使えず、"r" だけだと読み込み専用で write() が使えません。書いてすぐ読み戻す 演習では "w+" が必須になります。
理解度チェック
まずは1問ずつ答えてみましょう。
Q2tempfile.NamedTemporaryFile を delete=False 付き で使う典型的な理由として正しいのはどれですか?
Q3アトミック書き込み の本質は次のうちどれですか?