Вот код:
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, очевидно, работает. Я нашел обходной путь, который я опубликую. Однако есть ли лучшее объяснение и / или обходной путь?
Я предполагаю, что вызов shutil.rmtree возвращается до того, как ОС полностью завершит удаление всех файлов и подкаталогов. Кроме того, поскольку вызов shutil.rmtree не вызывает исключение, любая ошибка EACCESS (13) в вызове makedirs, вероятно, является поддельной. Моя попытка (измененная после комментария Апалалы):
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
Кажется, это работает надежно. Существует проблема расы, упомянутая в других постах, однако она кажется маловероятной и, вероятно, приведет к другому исключению.