Pythonのshutilを徹底解説! ファイル・ディレクトリ操作をパワフルに
Pythonでファイルやディレクトリのコピー、移動、削除といった操作をするとき、組み込みのos
モジュールだけでは少し物足りないと感じたことはありませんか? サブディレクトリを含んだコピーや、ディレクトリツリー全体の削除など、より高度なファイルシステム操作を簡潔に、そして安全に行いたいときに頼りになるのが、Pythonの標準ライブラリ**shutil
**です。
この記事では、shutil
の基本的な概念から、なぜファイル操作に不可欠なのか、そして実際に様々なファイル・ディレクトリ操作を実装する手順まで、初心者の方にも分かりやすく徹底的に解説します。shutil
をマスターして、あなたのPythonスクリプトにおけるファイルシステム操作をよりパワフルで効率的なものへと進化させましょう!
shutil
とは? なぜファイル・ディレクトリ操作に使うのか?
**shutil
**は、Pythonの標準ライブラリであり、高レベルのファイル操作(high-level file operations)を提供するモジュールです。shutil
の名前は “shell utilities” に由来し、UNIX/Linuxのシェルコマンド(cp
, mv
, rm
など)に似た機能を提供します。
なぜshutil
がファイル・ディレクトリ操作によく使われるのでしょうか?
高レベルな操作:
os
モジュールが提供する低レベルなファイル操作(例: ファイルの作成、リネーム)の上に構築されており、より複雑な操作(例: ディレクトリツリーのコピー、再帰的な削除)を単一の関数で実行できます。簡潔なコード: 複雑なファイル操作を数行のコードで実現できるため、コードの可読性が向上し、開発時間が短縮されます。
堅牢性: エラーハンドリングや権限の処理など、ファイルシステム操作で発生しがちな問題をある程度自動で処理するように設計されています。
標準ライブラリ: Pythonに最初から組み込まれているため、追加のインストールなしにすぐに利用できます。
クロスプラットフォーム: Windows、macOS、Linuxなど、異なるオペレーティングシステム間で一貫した動作を期待できます。
shutil
の基本的な使い方
shutil
の使い方は非常にシンプルです。主な操作は、コピー、移動、削除の3つです。
使用例を示すため、まず一時的なファイルとディレクトリを作成します。
import os
import shutil
# 作業ディレクトリの準備 (テスト用)
if not os.path.exists("test_dir"):
os.makedirs("test_dir")
os.chdir("test_dir") # test_dir に移動
with open("file1.txt", "w") as f:
f.write("Hello from file1.")
os.makedirs("subdir/nested", exist_ok=True)
with open("subdir/nested/file_in_subdir.txt", "w") as f:
f.write("Content in nested file.")
print("--- 初期状態のファイル構造 ---")
for root, dirs, files in os.walk("."):
level = root.replace('.', '').count(os.sep)
indent = ' ' * 4 * (level)
print(f"{indent}{os.path.basename(root)}/")
subindent = ' ' * 4 * (level + 1)
for f in files:
print(f"{subindent}{f}")
print("----------------------------")
1. コピー操作
shutil.copy(src, dst)
: ファイルのコピー
ファイルをコピーします。dst
がディレクトリの場合、そのディレクトリ内にファイル名はそのままでコピーされます。
# file1.txt を file1_copy.txt として同じディレクトリにコピー
shutil.copy("file1.txt", "file1_copy.txt")
print("`shutil.copy`でファイルをコピーしました。")
shutil.copy2(src, dst)
: ファイルのコピー(メタデータ含む)
copy
とほぼ同じですが、元のファイルのメタデータ(最終アクセス時刻、最終更新時刻、パーミッションなど)もコピーされます。
# file1.txt を subdir にコピー (subdir/file1.txt になる)
shutil.copy2("file1.txt", "subdir/")
print("`shutil.copy2`でファイルをsubdirにコピーしました。")
shutil.copytree(src, dst)
: ディレクトリツリーのコピー
ソースディレクトリ(src
)とその中身すべて(サブディレクトリ、ファイル)を、デスティネーションディレクトリ(dst
)に再帰的にコピーします。dst
は存在しないディレクトリでなければなりません。
# subdir 全体を new_subdir としてコピー
shutil.copytree("subdir", "new_subdir")
print("`shutil.copytree`でディレクトリツリーをコピーしました。")
2. 移動・リネーム操作
shutil.move(src, dst)
: ファイルやディレクトリの移動・リネーム
ファイルやディレクトリを移動します。dst
が既存のディレクトリの場合、src
はそのディレクトリ内に移動されます。dst
が存在しない場合、src
はdst
という名前にリネームされます。
# file1_copy.txt を new_name.txt にリネーム
shutil.move("file1_copy.txt", "new_name.txt")
print("`shutil.move`でファイルをリネームしました。")
# new_name.txt を subdir に移動
shutil.move("new_name.txt", "subdir/")
print("`shutil.move`でファイルをsubdirに移動しました。")
# new_subdir を renamed_subdir にリネーム
shutil.move("new_subdir", "renamed_subdir")
print("`shutil.move`でディレクトリをリネームしました。")
3. 削除操作
shutil.rmtree(path)
: ディレクトリツリーの削除
指定されたディレクトリとその中身すべて(サブディレクトリ、ファイル)を再帰的に削除します。非常に強力な操作なので、使用には細心の注意が必要です。
# renamed_subdir を削除
shutil.rmtree("renamed_subdir")
print("`shutil.rmtree`でディレクトリツリーを削除しました。")
その他の便利な機能
shutil
は上記以外にも便利な機能を提供します。
shutil.make_archive(base_name, format, root_dir)
: ディレクトリをZIPやtarなどのアーカイブ形式に圧縮します。Python# subdir ディレクトリを my_archive.zip として圧縮 shutil.make_archive("my_archive", "zip", "subdir") print("`shutil.make_archive`でディレクトリをzip圧縮しました。")
shutil.unpack_archive(filename, extract_dir, format)
: 圧縮されたアーカイブファイルを解凍します。Python# my_archive.zip を extracted_archive ディレクトリに解凍 os.makedirs("extracted_archive", exist_ok=True) shutil.unpack_archive("my_archive.zip", "extracted_archive", "zip") print("`shutil.unpack_archive`でzipファイルを解凍しました。")
shutil.disk_usage(path)
: 指定したパスのディスク使用量(合計、使用済み、空き容量)をバイト単位で返します。Pythontotal, used, free = shutil.disk_usage(".") print(f"ディスク使用量: 合計 {total / (1024**3):.2f} GB, 使用済み {used / (1024**3):.2f} GB, 空き {free / (1024**3):.2f} GB")
重要な注意点
shutil.rmtree()
の危険性: この関数は非常に強力で、指定したパスのファイルやディレクトリを問答無用で削除します。実行する前にパスが正しいことを十分に確認してください。特に、ユーザー入力や外部からのパスを直接rmtree
に渡すのは避けるべきです。権限とエラーハンドリング: ファイルシステム操作は、権限の問題やファイルが存在しないなどのエラーが発生しやすいです。
try-except
ブロックを使用して、適切にエラーを捕捉し、処理することが重要です。シンボリックリンク:
copytree
などの操作では、シンボリックリンクの扱いに注意が必要です。デフォルトではシンボリックリンクを指すファイル自体ではなく、リンク先のコンテンツがコピーされます。symlinks=True
オプションでシンボリックリンク自体をコピーすることもできます。
まとめ
shutil
モジュールは、Pythonでファイルやディレクトリを扱う際に非常に強力で便利なツールです。低レベルなos
モジュールと組み合わせることで、どんなファイルシステム操作も効率的に、そして簡潔に記述できるようになります。
高レベルなファイル操作を提供(コピー、移動、削除、圧縮、解凍)。
os
モジュールでは手間がかかるディレクトリツリーの再帰的な操作を簡単に行える。shutil.copy()
,shutil.move()
,shutil.rmtree()
,shutil.copytree()
が主要な関数。shutil.rmtree()
は強力なため、使用には細心の注意が必要。標準ライブラリなので追加インストール不要。
shutil
を使いこなすことで、Pythonスクリプトでのファイル整理、バックアップ、デプロイ準備など、様々なファイルシステム関連タスクをスマートに自動化できるでしょう。
最終クリーンアップ (上記コード実行後に手動で実行)
# test_dir から抜けて、test_dir を削除
cd ..
shutil.rmtree("test_dir")
print("テストディレクトリをクリーンアップしました。")
■プロンプトだけでオリジナルアプリを開発・公開してみた!!
■AI時代の第一歩!「AI駆動開発コース」はじめました!
テックジム東京本校で先行開始。
■テックジム東京本校
「武田塾」のプログラミング版といえば「テックジム」。
講義動画なし、教科書なし。「進捗管理とコーチング」で効率学習。
より早く、より安く、しかも対面型のプログラミングスクールです。
<短期講習>5日で5万円の「Pythonミニキャンプ」開催中。
<月1開催>放送作家による映像ディレクター養成講座
<オンライン無料>ゼロから始めるPython爆速講座