Функциональность mkdir -p в Python

Есть ли способ получить функциональность, похожую на mkdir -p на оболочку из Python. Я ищу решение, отличное от системного. Я уверен, что код меньше 20 строк, и мне интересно, кто-то уже написал его?

    12 Solutions collect form web for “Функциональность mkdir -p в Python”

    mkdir -p :

     import errno import os def mkdir_p(path): try: os.makedirs(path) except OSError as exc: # Python >2.5 if exc.errno == errno.EEXIST and os.path.isdir(path): pass else: raise 

    Обновить

    Для Python ≥ 3.2 os.makedirs имеет необязательный третий аргумент exist_ok который, когда true, включает функцию mkdir -pесли не предоставлен mode а существующий каталог имеет разные разрешения, чем предполагаемые; в этом случае OSError поднимается, как и ранее.

    В Python> = 3.2 это

     os.makedirs(path, exist_ok=True) 

    В более ранних версиях используйте ответ @ tzot .

    Это проще, чем захват исключения:

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

    Отказ от ответственности Этот подход требует двух системных вызовов, которые более подвержены условиям гонки в определенных условиях / условиях. Если вы пишете нечто более сложное, чем простой сценарий throwaway, работающий в контролируемой среде, вам лучше идти с принятым ответом, для которого требуется только один системный вызов.

    ОБНОВЛЕНИЕ 2012-07-27

    У меня возникает соблазн удалить этот ответ, но я думаю, что есть значение в комментариях ниже. Таким образом, я конвертирую его в wiki.

    Недавно я нашел distutils.dir_util.mkpath :

     In [17]: from distutils.dir_util import mkpath In [18]: mkpath('./foo/bar') Out[18]: ['foo', 'foo/bar'] 

    mkdir -p дает вам сообщение об ошибке, если файл уже существует:

     $ touch /tmp/foo $ mkdir -p /tmp/foo mkdir: cannot create directory `/tmp/foo': File exists 

    Таким образом, уточнение предыдущих предложений состояло бы в том, чтобы восстановить исключение, если os.path.isdir возвращает False (при проверке errno.EEXIST ).

    (Обновление) См. Также этот очень похожий вопрос ; Я согласен с принятым ответом (и оговорками), за исключением того, что я рекомендую os.path.isdir вместо os.path.exists .

    (Обновление) По предложению в комментариях полная функция будет выглядеть так:

     import os def mkdirp(directory): if not os.path.isdir(directory): os.makedirs(directory) 

    Как упоминалось в других решениях, мы хотим иметь возможность ударить файловую систему один раз, имитируя поведение mkdir -p . Я не думаю, что это можно сделать, но мы должны быть как можно ближе.

    Код сначала, объяснение позже:

     import os import errno def mkdir_p(path): """ 'mkdir -p' in Python """ try: os.makedirs(path) except OSError as exc: # Python >2.5 if exc.errno == errno.EEXIST and os.path.isdir(path): pass else: raise 

    Поскольку комментарии к ответу @ tzot указывают на наличие проблем с проверкой того, можно ли создать каталог до его создания: вы не можете сказать, изменил ли кто-то файловую систему тем временем. Это также соответствует стилю Питона просить прощения, а не разрешения.

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

    Как указывает Джейкоб Габриэльсон, один из случаев, который мы должны искать, – это тот случай, когда файл уже существует, где мы пытаемся поместить каталог.

    С mkdir -p :

     $ touch /tmp/foo $ mkdir -p /tmp/foo mkdir: cannot create directory '/tmp/foo': File exists 

    Аналогичным поведением в Python было бы создание исключения.

    Поэтому нам нужно разобраться, если это так. К сожалению, мы не можем. Мы получаем то же сообщение об ошибке от makedirs, существует ли каталог (хороший) или файл, препятствующий созданию директории (плохой).

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

    Единственная проблема заключается в том, что файловая система может находиться в другом состоянии, чем когда вызывались makedirs. например: существует файл, из-за которого makedirs терпят неудачу, но теперь на его месте находится каталог. Это не имеет большого значения, потому что функция будет работать только молча, не создавая исключения, когда на момент последней файловой системы вызывал каталог.

    Я думаю, что ответ Асы по существу правилен, но вы можете немного расширить его, чтобы больше походить на mkdir -p :

     import os def mkdir_path(path): if not os.access(path, os.F_OK): os.mkdirs(path) 

    или

     import os import errno def mkdir_path(path): try: os.mkdirs(path) except os.error, e: if e.errno != errno.EEXIST: raise 

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

    С Pathlib из стандартной библиотеки python3:

     Path(mypath).mkdir(parents=True, exist_ok=True) 

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

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

    Изменено в версии 3.5: Добавлен параметр exist_ok.

    Объявление функции;

     import os def mkdir_p(filename): try: folder=os.path.dirname(filename) if not os.path.exists(folder): os.makedirs(folder) return True except: return False 

    Применение :

     filename = "./download/80c16ee665c8/upload/backup/mysql/2014-12-22/adclient_sql_2014-12-22-13-38.sql.gz" if (mkdir_p(filename): print "Created dir :%s" % (os.path.dirname(filename)) 
     import os import tempfile path = tempfile.mktemp(dir=path) os.makedirs(path) os.rmdir(path) 

    У меня был успех со следующим лично, но моя функция, вероятно, должна называться чем-то вроде «обеспечить, чтобы этот каталог существовал»:

     def mkdirRecursive(dirpath): import os if os.path.isdir(dirpath): return h,t = os.path.split(dirpath) # head/tail if not os.path.isdir(h): mkdirRecursive(h) os.mkdir(join(h,t)) # end mkdirRecursive 
     import os from os.path import join as join_paths def mk_dir_recursive(dir_path): if os.path.isdir(dir_path): return h, t = os.path.split(dir_path) # head/tail if not os.path.isdir(h): mk_dir_recursive(h) new_path = join_paths(h, t) if not os.path.isdir(new_path): os.mkdir(new_path) 

    основанный на ответе @Dave C, но с исправленной ошибкой, когда часть дерева уже существует

    Python - лучший язык программирования в мире.