この記事では、指定したフォルダの全内容を、バージョン番号付きのZIPファイルとしてバックアップするPythonスクリプトの作成方法を解説します。os
、pathlib
、zipfile
モジュールを組み合わせて、実用的な自動化ツールを構築します。
1. 設計:バックアップ関数の処理フロー
作成するbackup_folder_to_zip
関数は、以下のステップで動作します。
- バックアップ対象のフォルダパスを絶対パスに変換します。
- 保存するZIPファイルの名前を決定します。もし
folder_1.zip
が既に存在すればfolder_2.zip
、folder_3.zip
…というように、まだ存在しない連番のファイル名を探します。 - 新しいZIPファイルを書き込みモードで作成します。
- 対象フォルダのディレクトリツリーを走査し、中のファイルと空のサブフォルダをすべてZIPファイルに追加します。ただし、過去に作成したバックアップZIPファイル自体は除外します。
2. 完成したコード全体
以下に、上記の設計を実装した完全なスクリプトを示します。
import os
import zipfile
from pathlib import Path
def backup_folder_to_zip(folder):
"""指定されたフォルダを連番付きのZIPファイルにバックアップする"""
# 1. パスの正規化とZIPファイル名の決定
folder_path = Path(folder).resolve() # 絶対パスに変換
base_name = folder_path.name
number = 1
while True:
zip_filename = f"{base_name}_{number}.zip"
if not Path(zip_filename).exists():
break
number += 1
# 2. 新しいZIPファイルの作成
print(f"作成中: {zip_filename}...")
with zipfile.ZipFile(zip_filename, 'w') as backup_zip:
# 3. ディレクトリツリーを走査してファイルを追加
for foldername, subfolders, filenames in os.walk(folder_path):
# 現在のフォルダをZIPに追加(空フォルダも保存される)
backup_zip.write(foldername)
# 各ファイルをZIPに追加
for filename in filenames:
# 既に作成済みのバックアップファイルはスキップ
if filename.startswith(base_name + '_') and filename.endswith('.zip'):
continue
file_to_add = Path(foldername) / filename
backup_zip.write(file_to_add)
print("バックアップが完了しました。")
# --- 関数の実行例 ---
# バックアップ対象のサンプルフォルダとファイルを作成
Path("my_project/images").mkdir(parents=True, exist_ok=True)
(Path("my_project") / "script.py").write_text("print('hello')")
(Path("my_project") / "notes.txt").write_text("important note")
(Path("my_project/images") / "logo.png").touch()
# 作成した関数を呼び出す
backup_folder_to_zip("my_project")
3. コードの解説
ファイル名の決定 while True:
ループの中で、Path(zip_filename).exists()
を使ってファイルが既に存在するかをチェックします。存在しなくなるまでnumber
を1ずつ増やし続けることで、my_project_1.zip
, my_project_2.zip
のように重複しないファイル名を生成します。
ZIPファイルへの書き込み with zipfile.ZipFile(zip_filename, 'w') as backup_zip:
でZIPファイルを書き込みモードで開きます。with
文を使うことで、処理が終わった後に自動でファイルが閉じられるため安全です。
os.walk()
を使って対象フォルダ内を走査し、見つかったフォルダパスとファイルパスをbackup_zip.write()
でアーカイブに追加していきます。このとき、ファイル名が過去のバックアップファイル(例: my_project_1.zip
)のパターンに一致する場合は、continue
で処理をスキップし、バックアップが無限に大きくならないようにしています。
まとめ
このスクリプトは、Pythonの標準ライブラリだけで、実用的なバックアップツールを作成できることを示しています。pathlib
でOSに依存しないパス操作を行い、os.walk
でディレクトリ構造を効率的に探索し、zipfile
でアーカイブを作成するという、各モジュールの強みを組み合わせた良い例です。