みーのぺーじ

みーが趣味でやっているPCやソフトウェアについて.Python, Javascript, Processing, Unityなど.

Pythonでディレクトリを作成する

基本的なことですが,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 ドキュメント

ソースコードを変更できない

他人が作成したライブラリで上記の如く実装されていて,簡単に変更ができない場合は,該当箇所が実行される前に予めディレクトリを作成しておくという対処方法もあります.