Como posso criar com segurança um diretório aninhado?

4249

Qual é a maneira mais elegante de verificar se o diretório em que um arquivo será gravado existe e, se não, criar o diretório usando Python? Aqui está o que eu tentei:

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)

De alguma forma, eu perdi os.path.exists(obrigado kanja, Blair e Douglas). Isto é o que eu tenho agora:

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

Existe uma bandeira para "aberto", que faz isso acontecer automaticamente?

Parand
fonte
27
Em geral, você pode precisar dar conta do caso em que não há diretório no nome do arquivo. Na minha máquina, dirname ('foo.txt') fornece '', que não existe e faz com que makedirs () falhe.
Brian Hawkins
11
No python 2.7 os.path.mkdirnão existe. É os.mkdir.
drevicko 6/07/2013
6
se o caminho existe, é necessário não apenas verificar se é um diretório e não um arquivo comum ou outro objeto (muitas respostas verificam isso), também é necessário verificar se é gravável (não encontrei uma resposta que verifique isso)
miracle173
9
Caso você tenha vindo aqui para criar diretórios-pai da cadeia de caracteres do caminho do arquivo p, aqui está o meu trecho de código:os.makedirs(p[:p.rindex(os.path.sep)], exist_ok=True)
Thamme Gowda

Respostas:

5193

No Python ≥ 3.5, use pathlib.Path.mkdir:

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

Para versões mais antigas do Python, vejo duas respostas com boas qualidades, cada uma com uma pequena falha, por isso vou dar a minha opinião:

Tente os.path.existse considere os.makedirsa criação.

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

Conforme observado nos comentários e em outros lugares, há uma condição de corrida - se o diretório for criado entre os.path.existsas os.makedirschamadas e as chamadas, a os.makedirsfalha será com um OSError. Infelizmente, a captura OSErrore a continuação de mantas não são infalíveis, pois ignoram a falha na criação do diretório devido a outros fatores, como permissões insuficientes, disco cheio, etc.

Uma opção seria interceptar OSErrore examinar o código de erro incorporado (consulte Existe uma maneira de obter várias plataformas de obter informações do OSError do Python ):

import os, errno

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

Como alternativa, pode haver um segundo os.path.exists, mas suponha que outro criou o diretório após a primeira verificação e o removeu antes da segunda - ainda poderíamos ser enganados.

Dependendo do aplicativo, o perigo de operações simultâneas pode ser mais ou menos do que o perigo causado por outros fatores, como permissões de arquivo. O desenvolvedor precisaria saber mais sobre o aplicativo específico que está sendo desenvolvido e seu ambiente esperado antes de escolher uma implementação.

As versões modernas do Python aprimoram bastante esse código, expondo FileExistsError(no 3.3 +) ...

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

... e permitindo que um argumento de palavra-chave seja os.makedirschamadoexist_ok (em 3.2+).

os.makedirs("path/to/directory", exist_ok=True)  # succeeds even if directory exists.
Blair Conrad
fonte
5
A condição de corrida é um bom ponto, mas a abordagem em stackoverflow.com/questions/273192/#273208 ocultará uma falha na criação do diretório. Não se sinta mal por votar - você não gosta da resposta. É para isso que servem os votos.
Blair Conrad
27
Lembre-se de que os.path.exists () não é gratuito. Se o caso normal é que o diretório estará lá, o caso em que não está deve ser tratado como uma exceção. Em outras palavras, tente abrir e gravar em seu arquivo, capture a exceção OSError e, com base em errno, faça seu makedir () e tente novamente ou aumente novamente. Isso cria duplicação de código, a menos que você envolva a gravação em um método local.
28411 Andrew
22
os.path.existstambém retorna Truepara um arquivo. Eu postei uma resposta para resolver isso.
Acumenos
13
Como comentaram outras respostas aqui, o exists_okparâmetro a os.makedirs()pode ser usado para cobrir como a existência anterior do caminho é tratada, desde o Python 3.2.
Bobble
6
os.mkdirs()pode criar pastas indesejadas se um separador de caminhos for acidentalmente deixado de fora, a pasta atual não for como o esperado, um elemento de caminho conterá o separador de caminhos. Se você usar os.mkdir()esses erros, haverá uma exceção, alertando você sobre a existência deles.
Drevicko 06/07/2013
1242

Python 3.5 ou superior:

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

pathlib.Path.mkdirconforme usado acima, recursivamente cria o diretório e não gera uma exceção se o diretório já existir. Se você não precisa ou deseja que os pais sejam criados, pule o parentsargumento.

Python 3.2 ou superior:

Usando pathlib:

Se puder, instale o pathlibbackport atual nomeado pathlib2. Não instale o backport não mantido mais antigo chamado pathlib. Em seguida, consulte a seção Python 3.5+ acima e use-a da mesma forma.

Se você estiver usando o Python 3.4, mesmo que o acompanhe pathlib, está faltando a exist_okopção útil . O backport destina-se a oferecer uma implementação mais nova e superior, mkdirque inclui essa opção ausente.

Usando os:

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

os.makedirsconforme usado acima, recursivamente cria o diretório e não gera uma exceção se o diretório já existir. Ele possui o exist_okargumento opcional apenas se você estiver usando o Python 3.2+, com um valor padrão de False. Este argumento não existe no Python 2.x até 2.7. Como tal, não há necessidade de manipulação manual de exceções, como no Python 2.7.

Python 2.7+:

Usando pathlib:

Se puder, instale o pathlibbackport atual nomeado pathlib2. Não instale o backport não mantido mais antigo chamado pathlib. Em seguida, consulte a seção Python 3.5+ acima e use-a da mesma forma.

Usando os:

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

Embora uma solução ingênua possa ser usada primeiro os.path.isdirseguida por os.makedirs, a solução acima reverte a ordem das duas operações. Ao fazer isso, evita que uma condição de corrida comum tenha a ver com uma tentativa duplicada de criar o diretório e também desambigua arquivos dos diretórios.

Observe que capturar a exceção e usar errnoé de utilidade limitada porque OSError: [Errno 17] File exists, ou seja errno.EEXIST, é gerado para arquivos e diretórios. É mais confiável simplesmente verificar se o diretório existe.

Alternativa:

mkpathcria o diretório aninhado e não faz nada se o diretório já existir. Isso funciona no Python 2 e 3.

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

De acordo com o Bug 10948 , uma limitação grave dessa alternativa é que ela funciona apenas uma vez por processo python para um determinado caminho. Em outras palavras, se você usá-lo para criar um diretório, exclua o diretório de dentro ou fora do Python, use mkpathnovamente para recriar o mesmo diretório, mkpathsimplesmente usará silenciosamente suas informações em cache inválidas de ter criado o diretório anteriormente e não o fará. faça o diretório novamente. Por outro lado, os.makedirsnão depende desse cache. Essa limitação pode ser boa para alguns aplicativos.


No que diz respeito ao modo do diretório , consulte a documentação se você se importa.

Acumenus
fonte
13
Essa resposta abrange praticamente todos os casos especiais, até onde eu sei. Eu planejo agrupar isso em um "se não os.path.isdir ()", porém, já que espero que o diretório exista quase sempre e posso evitar a exceção dessa maneira.
Charles L.
5
@CharlesL. Uma exceção é provavelmente mais barata que a E / S de disco da verificação, se o motivo for o desempenho.
jpmc26
1
@ jpmc26 mas o makedirs faz stat adicional, umask, lstat ao verificar apenas para lançar o OSError.
precisa saber é o seguinte
4
Esta é a resposta errada, uma vez que apresenta um potencial cond. Veja a resposta de Aaron Hall.
sleepycal
4
como o @sleepycal disse, isso sofre de uma condição de corrida semelhante à da resposta aceita. Se entre o aumento do erro e a verificação de os.path.isdiroutra pessoa excluir a pasta, você gerará o erro errado, desatualizado e confuso dessa pasta.
farmir
604

O uso de try except e o código de erro correto do módulo errno se livra da condição de corrida e é multiplataforma:

import os
import errno

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

Em outras palavras, tentamos criar os diretórios, mas se eles já existem, ignoramos o erro. Por outro lado, qualquer outro erro é relatado. Por exemplo, se você criar o diretório 'a' de antemão e remover todas as permissões dele, será OSErrorgerado um errno.EACCESerro com (Permissão negada, erro 13).

Heikki Toivonen
fonte
24
A resposta aceita é realmente perigosa porque tem uma condição de corrida. No entanto, é mais simples; portanto, se você não tem conhecimento da condição de corrida ou pensa que não se aplicará a você, essa seria sua primeira escolha óbvia.
Heikki Toivonen
15
Gerar a exceção somente quando exception.errno != errno.EEXIST, inadvertidamente, ignorará o caso quando o caminho existir, mas for um objeto que não seja de diretório, como um arquivo. Idealmente, a exceção deve ser levantada se o caminho for um objeto que não seja de diretório.
Acumenus
178
Observe que o código acima é equivalente aos.makedirs(path,exist_ok=True)
Navin
58
@ Navin O exist_okparâmetro foi introduzido no Python 3.2. Não está presente no Python 2.x. Vou incorporá-lo na minha resposta.
Acumenus
26
@HeikkiToivonen Tecnicamente falando, se outro programa estiver modificando os diretórios e arquivos ao mesmo tempo que o seu programa, todo o programa será uma condição de corrida gigantesca. O que impede um outro programa de excluir este diretório depois que o código o cria e antes de realmente colocar arquivos nele?
jpmc26
102

Eu pessoalmente recomendo que você use os.path.isdir()para testar em vez de 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

Se você tem:

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

E uma entrada tola do usuário:

:: /tmp/dirname/filename.etc

... Você terminará com um diretório nomeado filename.etcquando passar esse argumento para os.makedirs()se testar os.path.exists().

Peter Mortensen
fonte
8
Se você usar apenas 'isdir', ainda não terá um problema ao tentar criar o diretório e um arquivo com o mesmo nome já existe?
MrWonderful
3
@MrWonderful A exceção resultante ao criar um diretório sobre um arquivo existente refletiria corretamente o problema de volta ao chamador.
Damian Yerrick
79

Verifique os.makedirs: (Ele garante que o caminho completo exista.)
Para lidar com o fato de que o diretório possa existir, pegue OSError. (Se exist_okfor False(o padrão), um OSErrorserá gerado se o diretório de destino já existir.)

import os
try:
    os.makedirs('./path/to/somewhere')
except OSError:
    pass
Douglas Mayle
fonte
19
com o try / exceto, você irá mascarar erros na criação de diretório, no caso quando o diretório não existir, mas por algum motivo você não pode fazer isso
Blair Conrad
3
OSErrorserá gerado aqui se o caminho for um arquivo ou diretório existente. Eu postei uma resposta para resolver isso.
Acumenus 16/01
4
Isso é meio caminho andado. Você precisa verificar a condição de erro secundário OSErrorantes de decidir ignorá-la. Consulte stackoverflow.com/a/5032238/763269 .
Chris Johnson
71

A partir do Python 3.5, pathlib.Path.mkdirtem uma exist_okbandeira:

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

Isso cria recursivamente o diretório e não gera uma exceção se o diretório já existir.

(assim como os.makedirsobteve uma exist_okflag a partir do python 3.2, por exemplo os.makedirs(path, exist_ok=True))

hiro protagonista
fonte
46

Insights sobre as especificidades desta situação

Você fornece um arquivo específico em um determinado caminho e extrai o diretório do caminho do arquivo. Depois de verificar se você possui o diretório, tente abrir um arquivo para leitura. Para comentar sobre este código:

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

Queremos evitar a substituição da função interna dir,. Além disso, filepathou talvez fullfilepathseja, provavelmente, um nome semântico melhor do que filenameisso, seria melhor escrito:

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

Seu objetivo final é abrir esse arquivo, você declara inicialmente, para escrever, mas você está essencialmente se aproximando desse objetivo (com base no seu código) assim, que abre o arquivo para leitura :

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

Assumindo abertura para leitura

Por que você criaria um diretório para um arquivo que espera estar lá e possa ler?

Apenas tente abrir o arquivo.

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

Se o diretório ou arquivo não estiver lá, você receberá um IOErrornúmero de erro associado: errno.ENOENTapontará para o número de erro correto, independentemente da sua plataforma. Você pode pegá-lo se quiser, por exemplo:

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

Supondo que estamos abrindo para escrever

Provavelmente é isso que você está querendo.

Nesse caso, provavelmente não estamos enfrentando nenhuma condição de corrida. Portanto, faça como estava, mas observe que, para escrever, você precisa abrir com o wmodo (ou aanexar). Também é uma prática recomendada do Python usar o gerenciador de contexto para abrir arquivos.

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

No entanto, digamos que temos vários processos Python que tentam colocar todos os dados no mesmo diretório. Então, podemos ter disputas sobre a criação do diretório. Nesse caso, é melhor encerrar a makedirschamada em um bloco de tentativa-exceção.

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)
Aaron Hall
fonte
34

Experimente a os.path.existsfunção

if not os.path.exists(dir):
    os.mkdir(dir)
foi
fonte
3
Eu ia comentar sobre a pergunta, mas queremos dizer os.mkdir? Meu python (2.5.2) não tem os.path.mkdir ....
Blair Conrad
1
Não existe os.path.mkdir()método. O módulo os.path implementa algumas funções úteis nos nomes de caminho .
Serge S.
31

Anotei o seguinte. Não é totalmente infalível.

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

Agora, como eu disse, isso não é realmente infalível, porque temos a possibilidade de não conseguir criar o diretório e outro processo de criação durante esse período.

Ali Afshar
fonte
Dois problemas: (1) você precisa verificar a condição de sub-erro do OSError antes de decidir verificar os.path.exists- consulte stackoverflow.com/a/5032238/763269 e (2) êxito ativado os.path.existsnão significa que o diretório exista, apenas que o caminho existe existe - pode ser um arquivo, um link simbólico ou outro objeto do sistema de arquivos.
Chris Johnson
24

Verifique se existe um diretório e crie-o, se necessário?

A resposta direta a isso é, assumindo uma situação simples em que você não espera que outros usuários ou processos mexam com seu diretório:

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

ou se a criação do diretório estiver sujeita às condições de corrida (ou seja, se após a verificação do caminho existir, algo já pode ter sido feito):

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

Mas talvez uma abordagem ainda melhor seja evitar o problema de contenção de recursos usando diretórios temporários por meio de tempfile:

import tempfile

d = tempfile.mkdtemp()

Aqui está o essencial do documento on-line:

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.

Novo no Python 3.5: pathlib.Pathcomexist_ok

Há um novo Pathobjeto (a partir do 3.4) com muitos métodos que você gostaria de usar com caminhos - um dos quais é mkdir.

(Por contexto, estou rastreando meu representante semanal com um script. Aqui estão as partes relevantes do código do script que me permitem evitar atingir o estouro de pilha mais de uma vez por dia para os mesmos dados.)

Primeiro as importações relevantes:

from pathlib import Path
import tempfile

Não precisamos lidar os.path.joinagora - basta juntar as partes do caminho com um /:

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

Em seguida, garanto que o diretório existe de maneira independente - o exist_okargumento aparece no Python 3.5:

directory.mkdir(exist_ok=True)

Aqui está a parte relevante da documentação :

Se exist_okfor verdade, as FileExistsErrorexceções serão ignoradas (o mesmo comportamento do POSIX mkdir -pcomando), mas apenas se o último componente do caminho não for um arquivo não-diretório existente.

Aqui está um pouco mais do script - no meu caso, não estou sujeito a uma condição de corrida, só tenho um processo que espera que o diretório (ou arquivos contidos) esteja lá e não tenho nada tentando remover o diretório.

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))

Pathos objetos precisam ser coagidos strantes que outras APIs que esperam strcaminhos possam usá-los.

Talvez o Pandas deva ser atualizado para aceitar instâncias da classe base abstrata os.PathLike,.

Aaron Hall
fonte
20

No Python 3.4, você também pode usar o novo pathlibmódulo :

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.
Antti Haapala
fonte
@JanuszSkonieczny pypi.python.org/pypi/pathlib2 é o backport mais recente. O mais antigo não é mantido.
Acumenus
Como indicado na primeira linha do leia-me; Mas o antigo backport ainda é válido para a resposta aqui. E não há nomeação de dor de cabeça. Não há necessidade de explicar por que e quando usar pathlibe onde pathlib2para os novos usuários, e eu acho que prós aqui vai descobrir a depreciação;)
Janusz Skonieczny
13

A documentação relevante do Python sugere o uso do estilo de codificação EAFP (mais fácil pedir perdão do que permissão) . Isso significa que o código

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

é melhor que a alternativa

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

A documentação sugere isso exatamente por causa da condição de corrida discutida nesta pergunta. Além disso, como outros mencionam aqui, há uma vantagem de desempenho em consultar uma vez em vez de duas vezes o sistema operacional. Finalmente, o argumento apresentado, potencialmente, a favor do segundo código em alguns casos - quando o desenvolvedor conhece o ambiente em que o aplicativo está sendo executado - só pode ser defendido no caso especial em que o programa configurou um ambiente privado para próprio (e outras instâncias do mesmo programa).

Mesmo nesse caso, essa é uma prática ruim e pode levar à depuração inútil longa. Por exemplo, o fato de definirmos as permissões para um diretório não deve nos deixar com as permissões de impressão definidas adequadamente para nossos propósitos. Um diretório pai pode ser montado com outras permissões. Em geral, um programa deve sempre funcionar corretamente e o programador não deve esperar um ambiente específico.

kavadias
fonte
11

No Python3 , os.makedirssuporta configuração exist_ok. A configuração padrão é False, o que significa que um OSErrorserá gerado se o diretório de destino já existir. Ao definir exist_okcomo True, OSError(o diretório existe) será ignorado e o diretório não será criado.

os.makedirs(path,exist_ok=True)

No Python2 , os.makedirsnão suporta configuração exist_ok. Você pode usar a abordagem na resposta de heikki-toivonen :

import os
import errno

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

Para uma solução de uma linha, você pode usar IPython.utils.path.ensure_dir_exists():

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

Na documentação : Verifique se existe um diretório. Se não existir, tente criá-lo e proteja-o contra uma condição de corrida, se outro processo estiver fazendo o mesmo.

tashuhka
fonte
Nova documentação do IPython disponível aqui .
Jkdev
3
Não IPythoné absolutamente garantido que o módulo esteja presente. Ele está presente nativamente no meu Mac, mas não em nenhuma das minhas instalações do Python no Linux. Basicamente, não é um dos módulos listados no Python Module Index .
Acumenos
1
Certo. Para instalar o pacote, basta executar o usual pip install ipythonou incluir a dependência no seu requirements.txt ou pom.xml . Documentação: ipython.org/install.html
tashuhka 21/10
9

Você pode usar mkpath

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

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

Observe que ele também criará os diretórios ancestrais.

Funciona para Python 2 e 3.

Dennis Golomazov
fonte
2
distutils.dir_utilnão faz parte da API pública distutil e tem problemas em ambientes com vários threads: bugs.python.org/issue10948
Pod
1
Sim. Conforme observado na primeira mensagem do bug, o problema distutils.dir_util.mkpathé que, se você criar um diretório, excluí-lo de dentro ou fora do Python e usá-lo mkpathnovamente, mkpathusará simplesmente suas informações em cache inválidas de ter criado o diretório anteriormente e na verdade, não crie o diretório novamente. Por outro lado, os.makedirsnão depende desse cache.
Acumenus 21/10
8

Eu uso os.path.exists(), aqui está um script Python 3 que pode ser usado para verificar se um diretório existe, criar um se ele não existir e excluí-lo se ele existir (se desejado).

Ele solicita aos usuários a entrada do diretório e pode ser facilmente modificado.

Michael Strobel
fonte
6

Você pode usar os.listdirpara isso:

import os
if 'dirName' in os.listdir('parentFolderPath')
    print('Directory Exists')
iPhynx
fonte
Isso não responde à pergunta
Georgy
6

Eu encontrei este Q / A e fiquei inicialmente intrigado com algumas das falhas e erros que estava recebendo. Estou trabalhando no Python 3 (v.3.5 em um ambiente virtual Anaconda em um sistema Arch Linux x86_64).

Considere esta estrutura de diretórios:

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

Aqui estão minhas experiências / notas, que esclarecem as coisas:

# ----------------------------------------------------------------------------
# [1] /programming/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
# ----------------------------------------------------------------------------

Conclusão: na minha opinião, o "Método 2" é mais robusto.

[1] Como posso criar um diretório se ele não existe?

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

Victoria Stuart
fonte
6

Eu vi as respostas de Heikki Toivonen e ABB e pensei nessa variação.

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
alissonmuller
fonte
6

Use este comando check e create dir

 if not os.path.isdir(test_img_dir):
     os.mkdir(test_img_dir)
Manivannan Murugavel
fonte
5

Por que não usar o módulo subprocesso se estiver executando em uma máquina que suporta comando mkdircom -popção? Funciona no python 2.7 e python 3.6

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

Deve fazer o truque na maioria dos sistemas.

Em situações em que a portabilidade não importa (por exemplo, usando o docker), a solução são 2 linhas limpas. Você também não precisa adicionar lógica para verificar se os diretórios existem ou não. Finalmente, é seguro executar novamente sem efeitos colaterais

Se você precisar de tratamento de erros:

from subprocess import check_call
try:
    check_call(['mkdir', '-p', 'path1/path2/path3'])
except:
    handle...
Geoff Paul Bremner
fonte
4

Se você considerar o seguinte:

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

significa que um diretório (caminho) existe E é um diretório. Então, para mim desta maneira, faz o que eu preciso. Para garantir que ela seja uma pasta (não um arquivo) e exista.

Ralph Schwerdt
fonte
Como isso responde a uma questão de criar um diretório?
Georgy
3

Chame a função create_dir()no ponto de entrada do seu programa / projeto.

import os

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

create_dir('Project directory')
Steffi Keran Rani J
fonte
3

Você precisa definir o caminho completo antes de criar o diretório:

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)

Isso funciona para mim e espero que funcione para você também

Hussam Kurd
fonte
1
import os
if os.path.isfile(filename):
    print "file exists"
else:
    "Your code here"

Onde seu código é aqui, use o comando (touch)

Isto irá verificar se o arquivo está lá, se não estiver, então ele será criado.

O mal existe
fonte