Как я могу безопасно создать вложенный каталог?

Каков наиболее элегантный способ проверить, существует ли каталог, в который будет записан файл, и, если нет, создать каталог с помощью Python? Вот что я попробовал:

import os

file_path = "/my/directory/filename.txt"
directory = os.path.dirname(file_path)

try:
    os.stat(directory)
except:
    os.mkdir(directory)       

f = file(filename)

Как-то мне не хватало os.path.exists(спасибо Канджа, Блэр и Дуглас). Вот что у меня сейчас:

def ensure_dir(file_path):
    directory = os.path.dirname(file_path)
    if not os.path.exists(directory):
        os.makedirs(directory)

Есть ли флаг «открыть», который делает это автоматически?

7.11.2008 18:56:45
В общем случае вам может потребоваться учитывать случай, когда в имени файла нет каталога. На моей машине dirname ('foo.txt') дает '', который не существует и приводит к сбою makedirs ().
Brian Hawkins 26.05.2010 23:30:21
В питоне 2.7 os.path.mkdirне существует. Это os.mkdir.
drevicko 6.07.2013 06:15:16
если путь существует, нужно не только проверить, является ли он каталогом, а не обычным файлом или другим объектом (многие ответы проверяют это), также необходимо проверить, доступен ли он для записи (я не нашел ответа, который проверял это)
miracle173 19.02.2014 19:52:54
Если вы пришли сюда, чтобы создать родительские каталоги строки пути к файлу p, вот мой фрагмент кода:os.makedirs(p[:p.rindex(os.path.sep)], exist_ok=True)
Thamme Gowda 25.10.2016 03:40:27
25 ОТВЕТОВ
РЕШЕНИЕ

На Python ≥ 3.5 используйте pathlib.Path.mkdir:

from pathlib import Path
Path("/my/directory").mkdir(parents=True, exist_ok=True)

Для более старых версий Python я вижу два ответа с хорошими качествами, каждый с небольшим недостатком, поэтому я сделаю это:

Попробуйте os.path.existsи рассмотрите os.makedirsдля создания.

import os
if not os.path.exists(directory):
    os.makedirs(directory)

Как отмечалось в комментариях и в других местах, существует условие состязания - если каталог создается между вызовами os.path.existsи os.makedirsвызовами, os.makedirsпроизойдет сбой с помощью OSError. К сожалению, общий поиск OSErrorи продолжение не являются надежными, так как они будут игнорировать сбой при создании каталога из-за других факторов, таких как недостаточные разрешения, полный диск и т. Д.

Один из вариантов - перехватить OSErrorи изучить встроенный код ошибки (см. Существует ли кроссплатформенный способ получения информации из Python OSError ):

import os, errno

try:
    os.makedirs(directory)
except OSError as e:
    if e.errno != errno.EEXIST:
        raise

В качестве альтернативы может существовать второй os.path.exists, но предположим, что другой создал каталог после первой проверки, а затем удалил его до второй проверки - нас все еще можно обмануть.

В зависимости от приложения опасность одновременных операций может быть больше или меньше опасности других факторов, таких как права доступа к файлам. Разработчик должен знать больше о конкретном разрабатываемом приложении и его ожидаемой среде, прежде чем выбирать реализацию.

Современные версии Python немного улучшают этот код, предоставляя FileExistsError(в версии 3.3+ ) ...

try:
    os.makedirs("path/to/directory")
except FileExistsError:
    # directory already exists
    pass

... и позволяя ключевому аргументу os.makedirsвызыватьсяexist_ok (в 3.2+).

os.makedirs("path/to/directory", exist_ok=True)  # succeeds even if directory exists.
5092
30.12.2019 09:23:24
Хорошим моментом является состояние гонки, но подход в stackoverflow.com/questions/273192/#273208 замаскирует ошибку при создании каталога. Не расстраивайтесь из-за того, что проголосовали - вам не нравится ответ. Для этого и нужны голоса.
Blair Conrad 7.11.2008 20:35:41
Помните, что os.path.exists () не является бесплатным. Если обычным случаем является то, что каталог будет там, то случай, когда он не будет, должен рассматриваться как исключение. Другими словами, попробуйте открыть и записать в свой файл, перехватить исключение OSError и, основываясь на errno, выполнить makedir () и повторить попытку или выполнить повторное повышение. Это создает дублирование кода, если вы не заключите запись в локальный метод.
Andrew 28.11.2011 19:10:39
os.path.existsтакже возвращается Trueдля файла. Я отправил ответ на этот вопрос.
Acumenus 14.02.2013 17:32:59
Как отмечалось здесь, в комментариях к другим ответам, exists_okпараметр to os.makedirs()может использоваться для описания того, как обрабатывается предшествующее существование пути, начиная с Python 3.2.
Bobble 20.05.2013 06:50:40
os.mkdirs()может создавать непреднамеренные папки, если разделитель пути случайно пропущен, текущая папка не соответствует ожидаемой, элемент пути содержит разделитель пути. Если вы используете os.mkdir()эти ошибки, возникнет исключение, предупреждающее вас об их существовании.
drevicko 6.07.2013 06:41:48

Попробуйте os.path.existsфункцию

if not os.path.exists(dir):
    os.mkdir(dir)
33
15.10.2015 16:05:12
Я собирался прокомментировать вопрос, но мы имеем в виду os.mkdir? Мой питон (2.5.2) не имеет os.path.mkdir ....
Blair Conrad 7.11.2008 19:01:39
Там нет os.path.mkdir()метода. Модуль os.path реализует некоторые полезные функции для путей .
Serge S. 21.05.2012 15:14:12

Проверьте os.makedirs: (Он гарантирует, что полный путь существует.)
Чтобы обработать тот факт, что каталог может существовать, перехватите OSError. (Если exist_okесть False(по умолчанию), то OSErrorподнимается, если целевой каталог уже существует.)

import os
try:
    os.makedirs('./path/to/somewhere')
except OSError:
    pass
79
16.05.2019 12:15:39
с помощью try / исключением вы будете маскировать ошибки при создании каталога, в случае, если каталог не существует, но по какой-то причине вы не можете его создать
Blair Conrad 7.11.2008 19:09:55
OSErrorбудет поднят здесь, если путь является существующим файлом или каталогом. Я отправил ответ на этот вопрос.
Acumenus 16.01.2013 17:33:50
Это на полпути там. Вы должны проверить условие под-ошибки, OSErrorпрежде чем принять решение игнорировать его. См. Stackoverflow.com/a/5032238/763269 .
Chris Johnson 14.10.2015 21:31:51

Я изложил следующее. Это не совсем надежно, хотя.

import os

dirname = 'create/me'

try:
    os.makedirs(dirname)
except OSError:
    if os.path.exists(dirname):
        # We are nearly safe
        pass
    else:
        # There was an error on creation, so make sure we know about it
        raise

Теперь, как я уже сказал, это не совсем надежно, потому что у нас есть возможность не создать каталог и создать другой процесс в течение этого периода.

30
31.05.2014 14:05:11
Ali Afshar 7.11.2008 21:33:43
Две проблемы: (1) вам нужно проверить состояние под-ошибки OSError, прежде чем принять решение о проверке os.path.exists- см. Stackoverflow.com/a/5032238/763269, и (2) успех os.path.existsне означает, что каталог существует, просто путь существует - это может быть файл, символическая ссылка или другой объект файловой системы.
Chris Johnson 25.06.2018 21:23:02

Я бы лично рекомендовал вам использовать os.path.isdir()для тестирования вместо os.path.exists().

>>> os.path.exists('/tmp/dirname')
True
>>> os.path.exists('/tmp/dirname/filename.etc')
True
>>> os.path.isdir('/tmp/dirname/filename.etc')
False
>>> os.path.isdir('/tmp/fakedirname')
False

Если у тебя есть:

>>> dir = raw_input(":: ")

И глупый пользовательский ввод:

:: /tmp/dirname/filename.etc

... Вы filename.etcполучите каталог с именем, когда передадите этот аргумент, os.makedirs()если будете тестировать с os.path.exists().

101
31.05.2014 14:06:06
Если вы используете только isdir, у вас не возникнет проблема, когда вы попытаетесь создать каталог, а файл с таким именем уже существует?
MrWonderful 18.02.2014 20:07:53
@MrWonderful Полученное исключение при создании каталога поверх существующего файла будет правильно отражать проблему обратно вызывающей стороне.
Damian Yerrick 25.07.2015 15:35:12

Использование try кроме и правильного кода ошибки из модуля errno избавляет от состояния гонки и является кроссплатформенным:

import os
import errno

def make_sure_path_exists(path):
    try:
        os.makedirs(path)
    except OSError as exception:
        if exception.errno != errno.EEXIST:
            raise

Другими словами, мы пытаемся создать каталоги, но если они уже существуют, мы игнорируем ошибку. С другой стороны, сообщается о любой другой ошибке. Например, если вы заранее создадите dir 'a' и удалите из него все разрешения, вы получите OSErrorповышение с errno.EACCES(Отказано в доступе, ошибка 13).

603
24.04.2017 01:55:54
Принятый ответ на самом деле опасен, потому что он имеет состояние гонки. Однако это проще, поэтому, если вы не знаете о состоянии гонки или думаете, что это не относится к вам, это будет вашим очевидным первым выбором.
Heikki Toivonen 7.05.2012 18:23:20
Вызывает исключение только тогда, когда exception.errno != errno.EEXISTнепреднамеренно будет игнорироваться случай, когда путь существует, но это не-каталогный объект, такой как файл. В идеале, исключение следует вызывать, если путь не является каталогом.
Acumenus 16.01.2013 17:13:21
Обратите внимание, что приведенный выше код эквивалентенos.makedirs(path,exist_ok=True)
Navin 9.02.2013 15:36:16
@Navin exist_okПараметр был введен в Python 3.2. Его нет в Python 2.x. Я включу это в свой ответ.
Acumenus 14.02.2013 17:46:44
@HeikkiToivonen С технической точки зрения, если другая программа изменяет каталоги и файлы в то же время, что и ваша программа, то вся ваша программа находится в одном гигантском состоянии гонки. Что может помешать другой программе просто удалить этот каталог после того, как код его создаст, и до того, как вы фактически поместите в него файлы?
jpmc26 29.04.2014 22:41:14

Python 3.5+:

import pathlib
pathlib.Path('/my/directory').mkdir(parents=True, exist_ok=True) 

pathlib.Path.mkdirкак используется выше, рекурсивно создает каталог и не вызывает исключение, если каталог уже существует. Если вам не нужно или вы хотите, чтобы родители были созданы, пропустите parentsаргумент.

Python 3.2+:

Использование pathlib:

Если можете, установите текущий pathlibбэкпорт с именем pathlib2. Не устанавливайте старый незарегистрированный бэкпорт с именем pathlib. Далее, обратитесь к разделу Python 3.5+ выше и используйте его так же.

При использовании Python 3.4, хотя он и поставляется pathlib, в нем отсутствует полезная exist_okопция. Бэкпорт предназначен для того, чтобы предложить более новую и превосходную реализацию, mkdirкоторая включает эту отсутствующую опцию.

Использование os:

import os
os.makedirs(path, exist_ok=True)

os.makedirsкак используется выше, рекурсивно создает каталог и не вызывает исключение, если каталог уже существует. Он имеет необязательный exist_okаргумент только при использовании Python 3.2+ со значением по умолчанию False. Этот аргумент не существует в Python 2.x до 2.7. Таким образом, нет необходимости в ручной обработке исключений, как в Python 2.7.

Python 2.7+:

Использование pathlib:

Если можете, установите текущий pathlibбэкпорт с именем pathlib2. Не устанавливайте старый незарегистрированный бэкпорт с именем pathlib. Далее, обратитесь к разделу Python 3.5+ выше и используйте его так же.

Использование os:

import os
try: 
    os.makedirs(path)
except OSError:
    if not os.path.isdir(path):
        raise

В то время как наивное решение может сначала использовать, os.path.isdirа затем последующее os.makedirs, решение, приведенное выше, меняет порядок двух операций. При этом он предотвращает общее состояние гонки, связанное с дублирующейся попыткой создания каталога, а также устраняет неоднозначность файлов из каталогов.

Обратите внимание, что захват исключения и его использование errnoимеют ограниченную полезность OSError: [Errno 17] File exists, т. Е. Возникает как errno.EEXISTдля файлов, так и для каталогов. Надежнее просто проверить, существует ли каталог.

Альтернатива:

mkpathсоздает вложенный каталог и ничего не делает, если каталог уже существует. Это работает как в Python 2, так и в 3.

import distutils.dir_util
distutils.dir_util.mkpath(path)

В соответствии с ошибкой 10948 , серьезным ограничением этой альтернативы является то, что она работает только один раз на процесс python для данного пути. Другими словами, если вы используете его для создания каталога, затем удаляете каталог изнутри или снаружи Python, а затем mkpathснова используете для воссоздания того же каталога, mkpathпросто молча будут использовать его неверную кэшированную информацию о том, что ранее создали каталог, и не будут на самом деле сделать каталог снова. Напротив, os.makedirsне полагается на любой такой кэш. Это ограничение может быть в порядке для некоторых приложений.


Что касается режима каталога , пожалуйста, обратитесь к документации, если вы заботитесь о нем.

1222
17.05.2018 17:16:23
Насколько я могу судить, этот ответ охватывает практически все частные случаи. Я планирую обернуть это в «если не os.path.isdir ()», так как я ожидаю, что каталог будет существовать почти каждый раз, и таким образом я могу избежать исключения.
Charles L. 26.04.2013 05:52:17
@CharlesL. Исключение, вероятно, дешевле, чем дисковый ввод-вывод чека, если ваша причина в производительности.
jpmc26 29.04.2014 22:39:07
@ jpmc26, но makedirs делает дополнительную статистику, umask, lstat при проверке только на выброс OSError.
kwarunek 19.09.2014 10:31:21
Это неправильный ответ, так как он вводит потенциальное условие гонки ФС. Смотрите ответ от Аарона Холла.
sleepycal 8.01.2016 15:20:49
как сказал @sleepycal, это страдает от того же состояния гонки, что и принятый ответ. Если между появлением ошибки и проверкой os.path.isdirкто-то еще удаляет папку, вы увидите ошибку, которая устарела и устарела, что папка существует.
farmir 27.04.2016 07:20:54

В соответствующей документации по Python предлагается использовать стиль кодирования EAFP (проще просить прощения, чем разрешения) . Это означает, что код

try:
    os.makedirs(path)
except OSError as exception:
    if exception.errno != errno.EEXIST:
        raise
    else:
        print "\nBE CAREFUL! Directory %s already exists." % path

лучше альтернативы

if not os.path.exists(path):
    os.makedirs(path)
else:
    print "\nBE CAREFUL! Directory %s already exists." % path

Документация предполагает это именно из-за состояния гонки, обсуждаемого в этом вопросе. Кроме того, как другие упоминают здесь, есть преимущество в производительности при запросе один раз, а не дважды ОС. Наконец, аргумент, выдвигаемый, возможно, в пользу второго кода в некоторых случаях - когда разработчик знает среду, в которой работает приложение - может быть защищен только в том особом случае, когда программа создала частную среду для сам (и другие экземпляры той же программы).

Даже в этом случае это плохая практика и может привести к длительной бесполезной отладке. Например, тот факт, что мы устанавливаем разрешения для каталога, не должен оставлять нас с впечатлением, что права доступа установлены для наших целей. Родительский каталог может быть смонтирован с другими разрешениями. В общем, программа должна всегда работать правильно, и программист не должен ожидать одну конкретную среду.

13
31.12.2017 03:12:48

Проверить, существует ли каталог, и создать его при необходимости?

Прямой ответ на это, если предположить простую ситуацию, когда вы не ожидаете, что другие пользователи или процессы будут связываться с вашим каталогом:

if not os.path.exists(d):
    os.makedirs(d)

или если создание каталога зависит от условий гонки (т. е. если после проверки пути существует, что-то еще, возможно, уже сделало это), сделайте это:

import errno
try:
    os.makedirs(d)
except OSError as exception:
    if exception.errno != errno.EEXIST:
        raise

Но, возможно, еще лучший подход - обойти проблему конфликта ресурсов, используя временные каталоги через tempfile:

import tempfile

d = tempfile.mkdtemp()

Вот основные сведения из онлайн-документа:

mkdtemp(suffix='', prefix='tmp', dir=None)
    User-callable function to create and return a unique temporary
    directory.  The return value is the pathname of the directory.

    The directory is readable, writable, and searchable only by the
    creating user.

    Caller is responsible for deleting the directory when done with it.

Новое в Python 3.5: pathlib.Pathсexist_ok

Появился новый Pathобъект (начиная с 3.4) с множеством методов, которые хотелось бы использовать с путями - один из которых есть mkdir.

(Для контекста я отслеживаю своего еженедельного представителя с помощью скрипта. Вот соответствующие части кода из скрипта, которые позволяют мне избегать переполнения стека более одного раза в день для одних и тех же данных.)

Сначала соответствующий импорт:

from pathlib import Path
import tempfile

Нам не нужно иметь дело os.path.joinсейчас - просто соедините части пути с помощью /:

directory = Path(tempfile.gettempdir()) / 'sodata'

Затем я идемпотентно гарантирую, что каталог существует - exist_okаргумент обнаруживается в Python 3.5:

directory.mkdir(exist_ok=True)

Вот соответствующая часть документации :

Если exist_okэто правда, FileExistsErrorисключения будут игнорироваться (то же самое поведение, что и POSIX mkdir -pкоманда), но только если последний компонент пути не является существующим файлом, не являющимся каталогом.

Вот немного больше сценария - в моем случае я не подвержен условию гонки, у меня есть только один процесс, который ожидает, что каталог (или содержащиеся файлы) будет там, и у меня нет ничего, что пыталось бы удалить каталог.

todays_file = directory / str(datetime.datetime.utcnow().date())
if todays_file.exists():
    logger.info("todays_file exists: " + str(todays_file))
    df = pd.read_json(str(todays_file))

Pathобъекты должны быть приведены к тому, strчтобы другие API, ожидающие strпути, могли их использовать.

Возможно, Панды должны быть обновлены, чтобы принимать экземпляры абстрактного базового класса os.PathLike.

24
7.07.2017 03:19:31

Понимание специфики этой ситуации

Вы указываете конкретный файл по определенному пути и извлекаете каталог из пути к файлу. Затем, убедившись, что у вас есть каталог, вы пытаетесь открыть файл для чтения. Чтобы прокомментировать этот код:

filename = "/my/directory/filename.txt"
dir = os.path.dirname(filename)

Мы хотим избежать перезаписи встроенной функции dir. Кроме того, filepathили, возможно, fullfilepathэто, вероятно, лучшее семантическое имя, чем filenameэто было бы лучше написать:

import os
filepath = '/my/directory/filename.txt'
directory = os.path.dirname(filepath)

Ваша конечная цель - открыть этот файл, который вы изначально указали для записи, но вы, по сути, приближаетесь к этой цели (основываясь на вашем коде) следующим образом, открывая файл для чтения :

if not os.path.exists(directory):
    os.makedirs(directory)
f = file(filename)

Предполагая открытие для чтения

Зачем вам делать каталог для файла, который вы ожидаете там и сможете прочитать?

Просто попробуйте открыть файл.

with open(filepath) as my_file:
    do_stuff(my_file)

Если каталог или файл не существует, вы получите IOErrorс соответствующим номером ошибки: errno.ENOENTбудет указывать на правильный номер ошибки независимо от вашей платформы. Вы можете поймать его, если хотите, например:

import errno
try:
    with open(filepath) as my_file:
        do_stuff(my_file)
except IOError as error:
    if error.errno == errno.ENOENT:
        print 'ignoring error because directory or file is not there'
    else:
        raise

Предполагая, что мы открыты для записи

Это, вероятно, то, что вы хотите.

В этом случае мы, вероятно, не сталкиваемся ни с какими условиями гонки. Так что просто делайте как вы, но учтите, что для записи вам нужно открыть с помощью wрежима (или aдобавить). На Python также рекомендуется использовать контекстный менеджер для открытия файлов.

import os
if not os.path.exists(directory):
    os.makedirs(directory)
with open(filepath, 'w') as my_file:
    do_stuff(my_file)

Однако, скажем, у нас есть несколько процессов Python, которые пытаются поместить все свои данные в один и тот же каталог. Тогда мы можем иметь разногласия по поводу создания каталога. В этом случае лучше всего обернуть makedirsвызов в блок try-Кроме.

import os
import errno
if not os.path.exists(directory):
    try:
        os.makedirs(directory)
    except OSError as error:
        if error.errno != errno.EEXIST:
            raise
with open(filepath, 'w') as my_file:
    do_stuff(my_file)
46
1.04.2016 21:54:27

В Python 3.4 вы также можете использовать новый pathlibмодуль :

from pathlib import Path
path = Path("/my/directory/filename.txt")
try:
    if not path.parent.exists():
        path.parent.mkdir(parents=True)
except OSError:
    # handle error; you can also catch specific errors like
    # FileExistsError and so on.
20
11.03.2015 20:50:01
@JanuszSkonieczny pypi.python.org/pypi/pathlib2 - это новый бэкпорт. Более старый не поддерживается.
Acumenus 6.12.2017 17:58:13
Как это указано в первой строке readme; P. Но старый бэкпорт все еще действителен для ответа здесь. И нет именной головной боли. Не нужно объяснять, почему и когда использовать pathlibи где pathlib2для новых пользователей, и я думаю, что профессионалы здесь определятся с осуждением;)
Janusz Skonieczny 11.12.2017 15:43:16

Я видел ответы Хейкки Тойвонена и АББ и думал об этом варианте.

import os
import errno

def make_sure_path_exists(path):
    try:
        os.makedirs(path)
    except OSError as exception:
        if exception.errno != errno.EEXIST or not os.path.isdir(path):
            raise
6
31.12.2017 03:14:29

Для однострочного решения вы можете использовать IPython.utils.path.ensure_dir_exists():

from IPython.utils.path import ensure_dir_exists
ensure_dir_exists(dir)

Из документации : убедитесь, что каталог существует. Если он не существует, попытайтесь создать его и защитить от состояния гонки, если другой процесс делает то же самое.

11
16.05.2019 12:25:51
Новая документация IPython доступна здесь .
jkdev 5.10.2016 03:33:40
IPythonМодуль абсолютно не гарантированно присутствовать. Он изначально присутствует на моем Mac, но не на любой из моих установок Linux Python. По сути, это не один из модулей, перечисленных в указателе модулей Python .
Acumenus 21.10.2016 04:06:29
Конечно. Для того чтобы установить пакет, просто запустить обычный pip install ipythonили включить зависимость в вашем requirements.txt или pom.xml . Документация: ipython.org/install.html
tashuhka 21.10.2016 08:44:00

Вы можете использовать os.listdirдля этого:

import os
if 'dirName' in os.listdir('parentFolderPath')
    print('Directory Exists')
6
30.09.2017 12:31:13
Это не отвечает на вопрос
Georgy 16.05.2019 12:28:35

Ты можешь использовать mkpath

# Create a directory and any missing ancestor directories. 
# If the directory already exists, do nothing.

from distutils.dir_util import mkpath
mkpath("test")    

Обратите внимание, что он также создаст каталоги предков.

Это работает для Python 2 и 3.

9
13.09.2016 21:44:56
distutils.dir_utilне является частью distutil public API и имеет проблемы в многопоточных средах: bugs.python.org/issue10948
Pod 27.09.2016 08:26:39
Да. Как отмечалось в первом сообщении об ошибке, проблема в distutils.dir_util.mkpathтом, что если вы создаете каталог, затем удаляете его изнутри или снаружи Python, а затем mkpathснова используете , mkpathпросто воспользуетесь неверной кэшированной информацией о том, что ранее создал каталог, и на самом деле не сделать каталог снова. Напротив, os.makedirsне полагается на любой такой кэш.
Acumenus 21.10.2016 04:38:43

Если вы считаете следующее:

os.path.isdir('/tmp/dirname')

означает, что каталог (путь) существует И является каталогом. Так что для меня этот путь делает то, что мне нужно. Поэтому я могу убедиться, что это папка (а не файл) и существует.

4
3.12.2016 16:35:48
Как это отвечает на вопрос о создании каталога?
Georgy 16.05.2019 12:32:31

Начиная с Python 3.5, pathlib.Path.mkdirесть exist_okфлаг:

from pathlib import Path
path = Path('/my/directory/filename.txt')
path.parent.mkdir(parents=True, exist_ok=True) 
# path.parent ~ os.path.dirname(path)

Это рекурсивно создает каталог и не вызывает исключение, если каталог уже существует.

(так же, как os.makedirsполучил exist_okфлаг, начиная с Python 3.2, например os.makedirs(path, exist_ok=True))

70
17.12.2018 07:05:04

В Python3 , os.makedirsустановка опор exist_ok. По умолчанию используется значение False, которое означает, что OSErrorбудет поднято, если целевой каталог уже существует. Установив exist_okв True, OSError(каталог существует) будет игнорироваться и каталог не будет создан.

os.makedirs(path,exist_ok=True)

В python2 , os.makedirsне поддерживает установку exist_ok. Вы можете использовать подход в ответе Хейкки-Тойвонена :

import os
import errno

def make_sure_path_exists(path):
    try:
        os.makedirs(path)
    except OSError as exception:
        if exception.errno != errno.EEXIST:
            raise
11
23.05.2017 12:26:31

Я использую os.path.exists(), вот сценарий Python 3, который можно использовать для проверки, существует ли каталог, создать его, если он не существует, и удалить его, если он существует (при желании).

Он предлагает пользователям ввести каталог и может быть легко изменен.

8
31.12.2017 03:16:11
import os
if os.path.isfile(filename):
    print "file exists"
else:
    "Your code here"

Где ваш код здесь, используйте команду (touch)

Это проверит, если файл там, если это не так, то он создаст его.

1
5.07.2017 23:15:27

Я нашел это Q / A, и я был первоначально озадачен некоторыми сбоями и ошибками, которые я получал. Я работаю в Python 3 (v.3.5 в виртуальной среде Anaconda в системе Arch Linux x86_64).

Рассмотрим эту структуру каталогов:

└── output/         ## dir
   ├── corpus       ## file
   ├── corpus2/     ## dir
   └── subdir/      ## dir

Вот мои эксперименты / заметки, которые проясняют вещи:

# ----------------------------------------------------------------------------
# [1] https://stackoverflow.com/questions/273192/how-can-i-create-a-directory-if-it-does-not-exist

import pathlib

""" Notes:
        1.  Include a trailing slash at the end of the directory path
            ("Method 1," below).
        2.  If a subdirectory in your intended path matches an existing file
            with same name, you will get the following error:
            "NotADirectoryError: [Errno 20] Not a directory:" ...
"""
# Uncomment and try each of these "out_dir" paths, singly:

# ----------------------------------------------------------------------------
# METHOD 1:
# Re-running does not overwrite existing directories and files; no errors.

# out_dir = 'output/corpus3'                ## no error but no dir created (missing tailing /)
# out_dir = 'output/corpus3/'               ## works
# out_dir = 'output/corpus3/doc1'           ## no error but no dir created (missing tailing /)
# out_dir = 'output/corpus3/doc1/'          ## works
# out_dir = 'output/corpus3/doc1/doc.txt'   ## no error but no file created (os.makedirs creates dir, not files!  ;-)
# out_dir = 'output/corpus2/tfidf/'         ## fails with "Errno 20" (existing file named "corpus2")
# out_dir = 'output/corpus3/tfidf/'         ## works
# out_dir = 'output/corpus3/a/b/c/d/'       ## works

# [2] https://docs.python.org/3/library/os.html#os.makedirs

# Uncomment these to run "Method 1":

#directory = os.path.dirname(out_dir)
#os.makedirs(directory, mode=0o777, exist_ok=True)

# ----------------------------------------------------------------------------
# METHOD 2:
# Re-running does not overwrite existing directories and files; no errors.

# out_dir = 'output/corpus3'                ## works
# out_dir = 'output/corpus3/'               ## works
# out_dir = 'output/corpus3/doc1'           ## works
# out_dir = 'output/corpus3/doc1/'          ## works
# out_dir = 'output/corpus3/doc1/doc.txt'   ## no error but creates a .../doc.txt./ dir
# out_dir = 'output/corpus2/tfidf/'         ## fails with "Errno 20" (existing file named "corpus2")
# out_dir = 'output/corpus3/tfidf/'         ## works
# out_dir = 'output/corpus3/a/b/c/d/'       ## works

# Uncomment these to run "Method 2":

#import os, errno
#try:
#       os.makedirs(out_dir)
#except OSError as e:
#       if e.errno != errno.EEXIST:
#               raise
# ----------------------------------------------------------------------------

Вывод: по моему мнению, «Метод 2» является более надежным.

[1] Как я могу создать каталог, если он не существует?

[2] https://docs.python.org/3/library/os.html#os.makedirs

6
16.12.2017 19:26:08

Используйте эту команду, проверьте и создайте каталог

 if not os.path.isdir(test_img_dir):
     os.mkdir(test_img_dir)
6
16.05.2019 19:07:54

Вызовите функцию create_dir()в точке входа вашей программы / проекта.

import os

def create_dir(directory):
    if not os.path.exists(directory):
        print('Creating Directory '+directory)
        os.makedirs(directory)

create_dir('Project directory')
3
28.04.2018 16:00:40

Почему бы не использовать модуль подпроцесса, если он работает на компьютере, который поддерживает команду mkdirс -pпараметром? Работает на Python 2.7 и Python 3.6

from subprocess import call
call(['mkdir', '-p', 'path1/path2/path3'])

Должен сделать трюк на большинстве систем.

В ситуациях, когда переносимость не имеет значения (например, с помощью Docker), решение состоит из двух строк. Вам также не нужно добавлять логику, чтобы проверить, существуют ли каталоги или нет. Наконец, безопасно перезапускать без каких-либо побочных эффектов

Если вам нужна обработка ошибок:

from subprocess import check_call
try:
    check_call(['mkdir', '-p', 'path1/path2/path3'])
except:
    handle...
5
16.05.2019 19:37:30

Вы должны установить полный путь перед созданием каталога:

import os,sys,inspect
import pathlib

currentdir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
your_folder = currentdir + "/" + "your_folder"

if not os.path.exists(your_folder):
   pathlib.Path(your_folder).mkdir(parents=True, exist_ok=True)

Это работает для меня и, надеюсь, это будет работать и для вас

3
19.05.2019 00:40:45