72

クラスターシステム上でPythonから並行して実行されているいくつかのスレッドがあります。各Pythonスレッドはディレクトリに出力しますmydir。各スクリプトは、出力する前に、mydirが存在するかどうかを確認し、存在しない場合は作成します。

if not os.path.isdir(mydir):
    os.makedirs(mydir)

ただし、これによりエラーが発生します。

os.makedirs(self.log_dir)                                             
  File "/usr/lib/python2.6/os.py", line 157, in makedirs
mkdir(name,mode)
OSError: [Errno 17] File exists

競合状態が原因である可能性があります。この場合、一方のジョブがdirを作成してから、もう一方のジョブがそれに到達します。これは可能ですか?もしそうなら、このエラーをどのように回避できますか?

競合状態かどうかわからないので、Pythonの他の問題がこの奇妙なエラーを引き起こす可能性があるかどうか疑問に思っていました。

4

5 に答える 5

129

Pythonの時点で>=3.2os.makedirs()3番目のオプションの引数を取ることができますexist_ok

os.makedirs(mydir, exist_ok=True)
于 2015-05-11T18:25:53.387 に答える
56

何かをチェックしてから行動するまでの間にコードを実行できるときはいつでも、競合状態になります。これを回避する1つの方法(およびPythonの通常の方法)は、例外を処理してから処理することです。

while True:
    mydir = next_dir_name()
    try:
        os.makedirs(mydir)
        break
    except OSError, e:
        if e.errno != errno.EEXIST:
            raise   
        # time.sleep might help here
        pass

予測可能な一連のディレクトリを作成しようとしているスレッドがたくさんある場合でも、多くの例外が発生しますが、最終的にはそこに到達します。その場合、dirを作成するスレッドを1つだけにする方がよい

于 2012-09-17T22:44:47.473 に答える
18

例外をキャッチし、errnoが17の場合は、無視します。isdirmakedirs呼び出しの間に競合状態がある場合に実行できるのは、これだけです。

ただし、同じ名前のファイルが存在する可能性もあります。その場合os.path.existsは戻りますが、 falseTrueが返されます。os.path.isdir

于 2012-09-17T22:37:56.680 に答える
2

私も同様の問題を抱えていましたが、これが私がしたことです

try:
   if not os.path.exists(os.path.dirname(mydir)):
       os.makedirs(os.path.dirname(mydir))
except OSError as err:
   print(err)

Description: Just checking if the directory already exist throws this error message [Errno 17] File exists because we are just checking if the directory name exist or not which will return the directory name of the mydir value being passed but not if it already exist or not. What is being missed is not checking if that directory already exist which can be done by checking the path with os.path.exists() and in there we passed the respective directory name.

于 2017-07-13T09:45:36.467 に答える
0

To ignore the dir or file exist error, you can try this:

    except OSError, e:
        if e.errno != 17:
            print("Error:", e)
于 2019-11-01T03:11:15.737 に答える