exception verificar - Como posso criar um diretório aninhado com segurança no Python?



diretorio existe (21)

Você pode usar os.listdir para isso:

import os
if 'dirName' in os.listdir('parentFolderPath')
    print('Directory Exists')

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 os.path.exists falta dos 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 "abrir", que faz isso acontecer automaticamente?


Verifique os.makedirs : (Certifique-se de que o caminho completo existe.)
Para lidar com o fato de o diretório poder existir, capture OSError. (Se exist_ok for False (o padrão), um OSError será gerado se o diretório de destino já existir.)

import os
try:
    os.makedirs('./path/to/somewhere')
except OSError:
    pass

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

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

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

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

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

Mas talvez uma abordagem ainda melhor seja contornar o problema de contenção de recursos, usando diretórios temporários via 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.Path com exist_ok

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

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

Em primeiro lugar as importações relevantes:

from pathlib import Path
import tempfile

Nós não temos que lidar com os.path.join agora - apenas junte as partes do caminho com um / :

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

Então eu identifico que o diretório existe - o argumento exist_ok aparece no Python 3.5:

directory.mkdir(exist_ok=True)

Aqui está a parte relevante da pathlib.Path.mkdir :

Se exist_ok for true, FileExistsError exceções FileExistsError serão ignoradas (o mesmo comportamento que o comando POSIX mkdir -p ), mas somente se o último componente de caminho não for um arquivo existente de não diretório.

Aqui está um pouco mais do script - no meu caso, eu não estou sujeito a uma condição de corrida, eu só tenho um processo que espera que o diretório (ou arquivos contidos) esteja lá, e eu 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))

Objetos de Path precisam ser coagidos para str antes de outras APIs que esperam que caminhos str possam usá-los.

Talvez os Pandas devam ser atualizados para aceitar instâncias da classe base abstrata, os.PathLike .


No Python3 , os.makedirs suporta a configuração de exist_ok . A configuração padrão é False , o que significa que um OSError será gerado se o diretório de destino já existir. Definindo exist_ok como True , o OSError (directory exists) será ignorado e o diretório não será criado.

os.makedirs(path,exist_ok=True)

No Python2 , os.makedirs não suportam a configuração de 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

Por que não usar o módulo de subprocesso se estiver executando em uma máquina que suporta idiomas de shell? Funciona em 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.


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 insensata do usuário:

:: /tmp/dirname/filename.etc

... Você vai acabar com um diretório chamado filename.etc quando passar esse argumento para os.makedirs() se você testar com os.path.exists() .


Eu vi as respostas de Heikki Toivonen e da share 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

Você pode usar o 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 o Python 2 e 3.


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 documentation : Assegure-se de que um diretório exista. Se ele não existir, tente criá-lo e proteja-o contra uma condição de corrida se outro processo estiver fazendo o mesmo.


Eu coloquei o seguinte abaixo. 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 digo, isso não é realmente infalível, porque temos a possibilidade de não criar o diretório e outro processo de criá-lo durante esse período.


Informações sobre as especificidades desta situação

Você dá um determinado arquivo em um determinado caminho e você puxa o diretório do caminho do arquivo. Então, depois de ter certeza de que você tem o diretório, você tenta abrir um arquivo para leitura. Para comentar este código:

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

Queremos evitar sobrescrever a função interna, dir . Além disso, filepath ou talvez fullfilepath é provavelmente um nome semântico melhor que o nome do filename então isso seria melhor escrito:

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

Seu objetivo final é abrir esse arquivo, inicialmente declarado, para escrever, mas você está essencialmente abordando esse objetivo (com base em seu código) assim, o 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 poderá 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 IOError com um número de erro associado: errno.ENOENT apontará 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

Assumindo que estamos abrindo para escrever

Isso é provavelmente o que você está querendo.

Nesse caso, provavelmente não estamos enfrentando nenhuma condição de corrida. Então faça o que você foi, mas note que para escrever, você precisa abrir com o modo w (ou a acrescentar). Também é uma prática recomendada do Python para 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 em Python que tentam colocar todos os seus dados no mesmo diretório. Então podemos ter contenção sobre a criação do diretório. Nesse caso, é melhor envolver a chamada makedirs em um bloco try-except.

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)

Utilize este comando check and create dir

 if not os.path.isdir(test_img_dir):
     os.mkdir(str("./"+test_img_dir))

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 questão. 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 colocado em frente, potencialmente, em favor do segundo código em alguns casos - quando o desenvolvedor sabe o ambiente em que o aplicativo está sendo executado - só pode ser defendido no caso especial de que o programa configurou um ambiente privado para em si (e outras instâncias do mesmo programa).

Mesmo nesse caso, essa é uma prática ruim e pode levar a depurações desnecessárias. 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 configuradas 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.


Eu uso os.path.exists() , here está um script do Python 3 que pode ser usado para verificar se existe um diretório, 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.


A partir do Python 3.5, pathlib.Path.mkdir tem um sinalizador 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)

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

(assim como os.makedirs tem um sinalizador exists_ok partir do python 3.2).


Experimente a função os.path.exists

if not os.path.exists(dir):
    os.mkdir(dir)

Eu encontrei este Q / A e inicialmente fiquei intrigado com algumas das falhas e erros que eu estava recebendo. Eu 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 / anotações, que esclarecem as coisas:

# ----------------------------------------------------------------------------
# [1] https://.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
# ----------------------------------------------------------------------------

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

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

[2] os.makedirs


Se você considerar o seguinte:

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

significa que existe um diretório (caminho) E é um diretório. Então, para mim, isso faz o que eu preciso. Então eu posso ter certeza que é pasta (não um arquivo) e existe.


No Python 3.4, você também pode usar o novo módulo 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.

Ao trabalhar com arquivos I / O, o importante a considerar é

TOCTTOU (tempo de cheque para tempo de uso)

Portanto, fazer uma verificação com if e depois ler ou gravar mais tarde pode acabar em uma exceção de E / S não manipulada. A melhor maneira de fazer isso é:

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

Embora isso possa não ser útil devido ao fato de que ele faria muito mais sentido como sendo uma funcionalidade "out of the box", um hack bastante simples seria construir uma classe com uma propriedade length :

class slist(list):
    @property
    def length(self):
        return len(self)

Você pode usá-lo assim:

>>> l = slist(range(10))
>>> l.length
10
>>> print l
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Essencialmente, é exatamente idêntico a um objeto de lista, com o benefício adicional de ter uma propriedade de length compatível com OOP.

Como sempre, sua milhagem pode variar.





python exception path directory operating-system