Попытка использовать open(filename, 'w' ) дает IOError: [Errno 2] Нет такого файла или каталога, если каталог не существует

Я пытаюсь создать и записать в текстовый файл с помощью Python. Я искал и не могу найти решение/причину этой ошибки.

Вот код, который не работает:

afile = 'D:\\temp\\test.txt'
outFile = open(afile, 'w' )
outFile.write('Test.')
outFile.close()

# Error: 2
# Traceback (most recent call last):
#   File "<maya console>", line 1, in <module>
# IOError: [Errno 2] No such file or directory: 'D:\\temp\\test.txt' #

Большинство ответов, которые я нашел, связаны с косой чертой на пути, поэтому...

I tried 'D:/temp/test.txt' and got an error.
I tried r'D:\temp\test.txt' and got an error.

Когда я пытаюсь создать файл в корне D:/, у меня все получается.

'D:/test.txt' works.
'D:\\test.txt' works.
r'D:\test.txt' works.

Кажется, я не могу создать нужный путь к каталогу при попытке создать файл. Каков правильный метод создания файлов по определенному пути с помощью Python в Windows (7)? Я неправильно понимаю, что может сделать open()? Создает ли он каталоги, если они не существуют, или мне нужно явно создать путь к каталогу, прежде чем использовать open() в режиме «записи» для создания файла?


person gonzalimator    schedule 12.09.2013    source источник
comment
open не создает каталог, проверьте этот ответ для решения stackoverflow.com/questions/273192/   -  person Zuljin    schedule 12.09.2013


Ответы (3)


Вы правы, предполагая, что родительский каталог для файла должен существовать, чтобы open завершился успешно. Самый простой способ справиться с этим — вызвать os.makedirs.

Из документации:

os.makedirs(путь[, режим])

Функция рекурсивного создания каталогов. Подобно mkdir(), но создает все каталоги промежуточного уровня, необходимые для содержания конечного каталога.

Таким образом, ваш код может работать примерно так:

filename = ...
dirname = os.path.dirname(filename)
if not os.path.exists(dirname):
    os.makedirs(dirname)
with open(filename, 'w'):
    ...
person David Heffernan    schedule 12.09.2013
comment
Когда вы имеете дело с файловой системой, EAFP всегда лучше, чем LBYL, потому что в противном случае есть огромные возможности для условий гонки. Просто try makedirs, и справиться с EEXIST, ничего не делая (или, если хотите, вы можете даже try open и справиться с ENOENT, попробовав makedirs…). - person abarnert; 12.09.2013
comment
Если вы действительно ищете временный файл, tempfile может быть более подходящим. - person Burhan Khalid; 12.09.2013
comment
@BurhanKhalid: Определенно… но если вам нужен определенный каталог вместо каталога по умолчанию (например, вам нужно гарантировать наличие каталога без пробелов), tempfile.NamedTemporaryFilemkstemp и т. д.) также не создает каталоги, поэтому он может все равно такая же проблема. - person abarnert; 12.09.2013
comment
Кстати, еще лучшее решение — обновиться до более современного Python. В версии 3.2 вы можете просто вызвать os.makedirs(dir, exist_ok=True). В 3.1 вы можете по крайней мере поймать FileExistsError вместо того, чтобы ловить OSError и проверять errno. - person abarnert; 12.09.2013
comment
@abarnert Использование EAFP вместо LBYL ничего не меняет в отношении условий гонки. Несмотря ни на что, существует гонка между вызовом makedirs и вызовом open. И всегда есть гонка внутри makedirs. Я согласен, что проверка на существование дерьмовая. Но так ловит исключение. Python 3.2 и exist_ok - правильный подход, но вопрос говорит о 2.7. - person David Heffernan; 12.09.2013
comment
Использование dir в качестве имени переменной не идеально - это имеет побочный эффект перезаписи встроенной dir(). - person davejagoda; 16.05.2017

Если вы попытаетесь создать файл в несуществующем каталоге, вы получите эту ошибку.

Сначала вам нужно убедиться, что каталог существует. Вы можете сделать это с помощью os.makedirs() в соответствии с этим ответом.

person paxdiablo    schedule 12.09.2013

В качестве альтернативы вы можете проверить, существует ли файл, прежде чем открывать его с помощью:

os.path.exists (afile)

Который либо скажет True, либо False, в зависимости от того, существует ли он.

person aMoon    schedule 07.10.2013