4

コードは次のとおりです。

def make_dir(dir_name):
 if os.path.exists(dir_name):
  shutil.rmtree(dir_name)
 try:
  os.makedirs(dir_name)
 except OSError, e:
  print "ErrorNo: %s (%s)" % (e.errno, errno.errorcode[e.errno])
  raise

ディレクトリがすでに存在する場合、次のようになります。

ErrorNo: 13 (EACCES)
Traceback (most recent call last):
  File "run_pnoise.py", line 167, in <module>
    make_dir("prep_dat")
  File "run_pnoise.py", line 88, in make_dir
    os.makedirs(dir_name)
  File "c:\Program Files (x86)\Python27\lib\os.py", line 157, in makedirs
    mkdir(name, mode)
WindowsError: [Error 5] Access is denied: 'prep_dat'

プログラムを再度実行すると、動作します。これは、shutil.rmtree呼び出しが明らかに動作しているため、プログラムが実際にディレクトリにアクセスできることを示しています。投稿する回避策を考え出しました。しかし、より良い説明や回避策はありますか?

私の想定では、OSがすべてのファイルとサブディレクトリの削除を完全に完了する前に、shutil.rmtree呼び出しが返されます。また、shutil.rmtree呼び出しは例外をスローしないため、makedirs呼び出しでのEACCESS(13)エラーは偽物である可能性があります。私の試み(アパラーラのコメントの後に修正された):

def make_dir(dir_name):
    retry = True
    if os.path.exists(dir_name):
        shutil.rmtree(dir_name)
    while retry:
        try:
            # per Apalala, sleeping before the makedirs() eliminates the exception!
            time.sleep(0.001)
            os.makedirs(dir_name)
        except OSError, e:
            #time.sleep(0.001) # moved to before the makedirs() call 
            #print "ErrorNo: %s (%s)" % (e.errno, errno.errorcode[e.errno])
            if e.errno != 13: # eaccess
                raise
        else:
            retry = False

これは確実に機能するようです。他の投稿で言及されている競合状態の問題がありますが、それはありそうもないようで、おそらく別の例外が発生するでしょう。

4

3 に答える 3

0

«except» ステートメントを単純に使用することはできませんか?

def make_dir(dir_name):
    retry = True
    if os.path.exists(dir_name):
        shutil.rmtree(dir_name)
    while retry:
        try:
            os.makedirs(dir_name)
        except OSError, e:
            time.sleep(0.001)
            if e.errno != 13: # eaccess
                raise
        except WindowsError:
#           (do some stuff)
        else:
            retry = False

うまくいくはずですよね?

于 2011-01-06T15:42:28.783 に答える
0

私は同じ問題を抱えていましたが、これは私の解決策と似ていますが、私は寝ていました(0.1)。

于 2011-01-05T22:33:25.193 に答える
0

以前の投稿で、プログラムが «WindowsError» 例外を発生させたと述べました。

WindowsError: [Error 5] Access is denied: 'prep_dat'

コードは «except» ステートメントを使用して «OSError» 例外を処理できますが、«WindowsError» 例外は処理できません... «WindowsError» 例外を処理したい場合は、次のように «except» ステートメントを使用する必要があります。

        except WindowsError:
#           (do some stuff)

次のような例外を処理できることに注意してください。

except Exception, e:
    # this code will catch all raised exceptions. The variable «e» contains an instance of the raised exception.
于 2011-01-12T13:30:24.437 に答える