基本的なことですが,Pythonでディレクトリを作成する時に遭遇したエラーについてまとめます.
FileExistsErrorに悩む
ScrapyというPython framework にて,FileExistsErrorが100回に1回ぐらい発生する現象に遭遇しました.
scrapy/extensions/feedexport.py
def open(self, spider): dirname = os.path.dirname(self.path) if dirname and not os.path.exists(dirname): os.makedirs(dirname) return open(self.path, self.write_mode)
dirname
が存在するかどうかを確認して,存在しなければ作成するという,なんの変哲もない処理です.これはシングルタスク環境では問題になりませんが,multiprocessingで複数のScrapyを同時に実行する時に問題となります.
このコードをほぼ同時に複数のプロセスで実行すると,
- プロセス1が
os.path.exists(dirname)
をFalseと評価する - プロセス2が
os.makedirs(dirname)
を実行する - プロセス1が
os.makedirs(dirname)
を実行する
ということが時々発生する可能性があり,FileExistsError
となるわけです.
exist_okを使うべき
os.makedirs(dirname, exist_ok=True)
を使えばよいです.ソースコードもシンプルになります.
os --- 雑多なオペレーティングシステムインタフェース — Python 3.9.1 ドキュメント
ソースコードを変更できない
他人が作成したライブラリで上記の如く実装されていて,簡単に変更ができない場合は,該当箇所が実行される前に予めディレクトリを作成しておくという対処方法もあります.