Pythonのshutilモジュールを活用したファイルシステム制御

概要

Python標準ライブラリに含まれるshutilは、低レベルなOS操作を行うosモジュールを補完するものとして設計されています。このモジュールを使うことで、ファイルやディレクトリのコピー、移動、削除、そしてアーカイブ生成といった、日常的なファイル管理タスクを直感的かつ安全に実装することが可能です。

ファイルのコピー処理

コピー機能にはメタデータ(権限、時刻情報)を保持するかどうかによって複数のバリエーションが存在します。

基本コピーと詳細属性の扱い

  • shutil.copy(src, dst): ファイル内容のみをコピーします。目的先ディレクトリが存在しない場合は作成され、同名ファイルが既にあれば上書きされます。
  • shutil.copyfile(src, dst): コンテンツの複製を行います。ただし、親ディレクトリが存在しない場合や、dstが既存ディレクトリを指している場合は例外が発生するため注意が必要です。
  • shutil.copy2(src, dst): ファイルの内容に加え、stat情報の所有者、グループ、アクセス権、タイムスタンプなども完全に複製します。バックアップ用途に適しています。
import shutil
import time

# ソースファイルを想定
source_file = "module_main.py"
target_file = "module_backup.py"

# copy2を使用し、時間情報を維持しながらコピー
shutil.copy2(source_file, target_file)

print(f"元の更新時刻: {time.ctime(__import__('os').stat(source_file).st_mtime)}")
print(f"コピー先の更新時刻: {time.ctime(__import__('os').stat(target_file).st_mtime)}")
# 両者の出力が一致することが期待されます

ストリーム単位および属性のみ転送

すでにオープンされているファイルオブジェクト間でデータを渡す際はcopyfileobjを利用します。また、コンテンツではなく「実行可能フラグ」などのパーミッションだけを転送したい場合はcopymodeが有効です。一方、統計情報全般(時刻含む)のみを適用したい時はcopystatを使用します。

# ファイルハンドルを使用した転送例
with open("input_data.log", "r") as src_handle:
    with open("output_data.log", "w") as dest_handle:
        # 内部バッファサイズを指定可能
        shutil.copyfileobj(src_handle, dest_handle, length=8192)

# パーミッションのみの複製
shutil.copymode("template.conf", "actual.conf")

ディレクトリ全体の複製

ディレクトリツリー全体を再帰的にコピーするにはcopytreeを使います。この際、宛先パスは未存在である必要があります。特定の拡張子を持つファイルを除外する必要がある場合は、ignoreパラメータでフィルタリング関数を定義するか、標準のignore_patternsを使用します。

# Pythonの特定パターンを除外してプロジェクトをダンプ
exclude_pattern = shutil.ignore_patterns('*.pyc', '__pycache__', '*.tmp')
shutil.copytree("./src_project", "./bak_project", ignore=exclude_pattern, copy_function=shutil.copy2)

移動と削除処理

ファイルやフォルダーの位置変更および永久的な削除には以下のメソッドが用いられます。

  • shutil.move(src, dst): ファイルの移動や名称変更が可能です。また、ディレクトリ同士であっても跨いで移動することができ、ネットワーク越しの移動もサポートしています。
  • shutil.rmtree(path): 指定されたディレクトリと、その中のすべてのサブディレクトリ・ファイルを非逆戻的に削除します。使用中の重要なデータに対して誤って実行すると取り返しがつかないため、使用時には十分な注意を要します。
# ファイルのリネーム兼移動
shutil.move("draft_v1.txt", "final_version.txt")

# フォルダ内のクリーンナップ(空でないフォルダでも削除可能)
shutil.rmtree("./temp_cache/")

データの圧縮と展開

バージョン管理や送信用としてデータをまとめたい場合、make_archiveおよびunpack_archiveが利用できます。zip形式だけでなく、tar、gztar、bztar、xztar等多种多樣なフォーマットに対応しています。

アーカイブの作成

# ドキュメントフォルダをZIP形式で圧縮
base_name = "project_package"
shutil.make_archive(base_name, 'zip', root_dir='./docs_files')

アーカイブの展開

# 圧縮済みファイルを指定フォルダへ解凍
archive_path = "project_package.zip"
destination_dir = "./restored_docs"

# format を省略すると、拡張子から自動判別される
shutil.unpack_archive(archive_path, extract_dir=destination_dir)

タグ: Python shutil file-management archiving automation

6月18日 18:59 投稿