久しぶりにおやすみの時間ができました。
そしてあるスタートアップで、事業開発していた人間がやめることになり、ドタバタ引継ぎ(といっても、pythonやGASが関与する部分だけ)しながら過ごしていたこの頃でした。
M&Aサポートしてる会社も新規事業関係でわちゃっとしてるし、落ち着かないまま9月に突入しそうですねぇ。
今日は引継ぎを受けたpythonスクリプトをいじってる際に少し不便だったファイルがあるフォルダの削除についてです。
やりたいこと(ユースケース)としては、フォルダ内のファイルの一括削除です。
フォルダ内のファイルを全部消す
文字通り実行する場合、os.removeで対象フォルダのファイルを正規表現で指定して、消す。ということになりますが、実はファイルの数が多いと地味に時間を食います。。
なので、今回はファイルを消すという概念ではなく、フォルダごと削除して、また新しい同一名称のフォルダを作成して、結果としてフォルダ内のファイルを空っぽにしていきます。
os.removedirsによる削除の欠点
まぁシンプルに最初はos.removedirsで対象フォルダを削除して、同一名称のフォルダを作成すれば完了、という気分でいましたので、以下のスクリプトを追加。
import os
target_folder = 'temp/'
os.removedirs(target_folder)
os.mkdir(target_folder)
結果が以下。
Traceback (most recent call last): File "folder_remove_mkdir.py", line 14, in os.removedirs(target_folder) File "/usr/local/Cellar/python/3.7.7/Frameworks/Python.framework/Versions/3.7/lib/python3.7/os.py", line 241, in removedirs rmdir(name) OSError: [Errno 66] Directory not empty: 'temp/'
あぁdirが空っぽじゃないとremovedirsは動作しないと。。それじゃやりたいことができない。。
dirにファイルがある場合でも削除する方法
ディレクトリにファイルがある場合に削除するには、shutilモジュールを利用すれば可能です。
ざっとこんな感じ。というか、os.removedirsの部分をshutil.rmtreeに変更しただけ。
import os
import shutil
target_folder = 'temp/'
shutil.rmtree(target_folder)
os.mkdir(target_folder)
これで実行可能です。こうすることにより、ファイルを一個一個os.removeで削除しなくてもすみます(こっちの方が実行処理時間も短い)。
一括して対象ディレクトリのファイルを削除する場合
対象dirをlist化してあげて、for inで回してあげれば可能です。以下のような感じ。
import shutil
import os
target_folders = ['data/', 'output/', 'output_pdf/', 'temp/'] #このリストにディレクトリをいれる
for folder in target_folders:
shutil.rmtree(folder)
os.mkdir(folder)
まとめ
別に標準モジュールを利用しているだけなので、知ってる人も多いと思います。
ただ、メソッドの利用前提条件などはたまに忘れますね、私だけかもしれませんが。