¿Cómo puedo crear de forma segura un directorio anidado?

4250

¿Cuál es la forma más elegante de verificar si el directorio en el que se va a escribir un archivo existe, y si no, crear el directorio usando Python? Esto es lo que probé:

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 alguna manera, extrañé os.path.exists(gracias kanja, Blair y Douglas). Esto es lo que tengo ahora:

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

¿Hay una bandera para "abrir" que hace que esto suceda automáticamente?

Desfile
fuente
27
En general, es posible que deba tener en cuenta el caso en el que no hay directorio en el nombre del archivo. En mi máquina, el nombre de directorio ('foo.txt') da '', que no existe y hace que makedirs () falle.
Brian Hawkins,
11
En python 2.7 os.path.mkdirno existe. Es os.mkdir.
drevicko
66
si la ruta existe, uno no solo tiene que verificar si es un directorio y no un archivo normal u otro objeto (muchas respuestas verifican esto) también es necesario verificar si es editable (no encontré una respuesta que verificara esto)
milagro173
99
En caso de que haya venido a crear directorios principales de la cadena de ruta de archivo p, aquí está mi fragmento de código:os.makedirs(p[:p.rindex(os.path.sep)], exist_ok=True)
Thamme Gowda

Respuestas:

5194

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

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

Para versiones anteriores de Python, veo dos respuestas con buenas cualidades, cada una con un pequeño defecto, por lo que daré mi opinión al respecto:

Prueba os.path.existsy considera os.makedirspara la creación.

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

Como se señaló en los comentarios y en otros lugares, hay una condición de carrera: si el directorio se crea entre os.path.existsy las os.makedirsllamadas, os.makedirsfallará con un OSError. Desafortunadamente, la cobijaOSError y la continuación no son infalibles, ya que ignorará una falla al crear el directorio debido a otros factores, como permisos insuficientes, disco completo, etc.

Una opción sería atrapar OSErrory examinar el código de error incrustado (consulte ¿Hay una manera multiplataforma de obtener información del OSError de Python? ):

import os, errno

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

Alternativamente, podría haber un segundo os.path.exists, pero supongamos que otro creó el directorio después de la primera verificación, luego lo eliminó antes de la segunda, aún podríamos engañarnos.

Dependiendo de la aplicación, el peligro de las operaciones concurrentes puede ser más o menos que el peligro que representan otros factores, como los permisos de archivos. El desarrollador tendría que saber más sobre la aplicación particular que se está desarrollando y su entorno esperado antes de elegir una implementación.

Las versiones modernas de Python mejoran bastante este código, tanto al exponer FileExistsError(en 3.3+) ...

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

... y al permitir que un argumento de palabra clave que os.makedirsse llamaexist_ok (en 3.2+).

os.makedirs("path/to/directory", exist_ok=True)  # succeeds even if directory exists.
Blair Conrad
fuente
55
La condición de carrera es un buen punto, pero el enfoque en stackoverflow.com/questions/273192/#273208 enmascarará un error al crear el directorio. No se sienta mal por votar, no le gusta la respuesta. Para eso están los votos.
Blair Conrad el
27
Recuerda que os.path.exists () no es gratis. Si el caso normal es que el directorio estará allí, entonces el caso en el que no está debería ser manejado como una excepción. En otras palabras, intente abrir y escribir en su archivo, detecte la excepción OSError y, en base a errno, haga su makedir () y vuelva a intentarlo o vuelva a subirlo. Esto crea duplicación de código a menos que ajuste la escritura en un método local.
Andrew
22
os.path.existsTambién vuelve Truepara un archivo. He publicado una respuesta para abordar esto.
Acumenus
13
Como los comentaristas de otras respuestas aquí han señalado, el exists_okparámetro a os.makedirs()se puede usar para cubrir cómo se maneja la existencia previa de la ruta, desde Python 3.2.
Bobble
66
os.mkdirs()puede crear carpetas no deseadas si se omite accidentalmente un separador de ruta, la carpeta actual no es la esperada, un elemento de ruta contiene el separador de ruta. Si usa os.mkdir()estos errores, se generará una excepción y le alertará sobre su existencia.
drevicko
1242

Python 3.5+:

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

pathlib.Path.mkdircomo se usa anteriormente, crea recursivamente el directorio y no genera una excepción si el directorio ya existe. Si no necesita o desea que se creen los padres, omita elparents argumento.

Python 3.2+:

Utilizando pathlib:

Si puede, instale el pathlibpuerto actual llamado pathlib2. No instale el backport sin mantenimiento anterior llamado pathlib. A continuación, consulte la sección Python 3.5+ anterior y úsela igual.

Si usa Python 3.4, aunque viene con pathlib, le falta la exist_okopción útil . El backport está destinado a ofrecer una implementación más nueva y superior mkdirque incluye esta opción que falta.

Utilizando os:

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

os.makedirscomo se usa anteriormente, crea recursivamente el directorio y no genera una excepción si el directorio ya existe. Tiene el exist_okargumento opcional solo si usa Python 3.2+, con un valor predeterminado deFalse . Este argumento no existe en Python 2.x hasta 2.7. Como tal, no hay necesidad de manejo manual de excepciones como con Python 2.7.

Python 2.7+:

Utilizando pathlib:

Si puede, instale el pathlibpuerto actual llamado pathlib2. No instale el backport sin mantenimiento anterior llamado pathlib. A continuación, consulte la sección Python 3.5+ anterior y úsela igual.

Utilizando os:

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

Mientras que una solución ingenua puede usarse primero, os.path.isdirseguida por os.makedirsla solución anterior, invierte el orden de las dos operaciones. Al hacerlo, evita que una condición de carrera común tenga que ver con un intento duplicado de crear el directorio, y también desambigua los archivos de los directorios.

Tenga en cuenta que capturar la excepción y usarlo errnoes de utilidad limitada porque OSError: [Errno 17] File exists, es decir errno.EEXIST, se genera para archivos y directorios. Es más confiable simplemente verificar si el directorio existe.

Alternativa:

mkpathcrea el directorio anidado y no hace nada si el directorio ya existe. Esto funciona en Python 2 y 3.

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

Según el error 10948 , una limitación severa de esta alternativa es que funciona solo una vez por proceso de Python para una ruta determinada. En otras palabras, si lo usa para crear un directorio, luego elimine el directorio desde dentro o fuera de Python, luego mkpathvuelva a usarlo para recrear el mismo directorio, mkpathsimplemente usará en silencio su información en caché no válida de haber creado previamente el directorio, y no lo hará. Realmente hacer el directorio de nuevo. Por el contrario, os.makedirsno se basa en tal caché. Esta limitación puede estar bien para algunas aplicaciones.


Con respecto al modo del directorio , consulte la documentación si le interesa.

Acumenus
fuente
13
Esta respuesta cubre casi todos los casos especiales hasta donde puedo decir. Sin embargo, planeo envolver esto en un "si no os.path.isdir ()", ya que espero que el directorio exista casi siempre y puedo evitar la excepción de esa manera.
Charles L.
55
@CharlesL. Una excepción es probablemente más barata que el disco IO de la verificación, si su razón es el rendimiento.
jpmc26
1
@ jpmc26 pero makedirs hace stat, umask, lstat adicionales cuando solo verifica para lanzar OSError.
kwarunek
44
Esta es la respuesta incorrecta, ya que introduce un potencial cond de carrera FS. Ver respuesta de Aaron Hall.
Sleepycal
44
Como ha dicho @sleepycal, esto tiene una condición de carrera similar a la respuesta aceptada. Si entre generar el error y verificar que os.path.isdirotra persona elimine la carpeta, generará el error incorrecto, desactualizado y confuso de que esa carpeta existe.
farmir
604

Usando try except y el código de error correcto del módulo errno elimina la condición de carrera y es 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

En otras palabras, intentamos crear los directorios, pero si ya existen ignoramos el error. Por otro lado, se informa cualquier otro error. Por ejemplo, si crea el directorio 'a' de antemano y le quita todos los permisos, obtendrá un OSErroraumento con errno.EACCES(Permiso denegado, error 13).

Heikki Toivonen
fuente
24
La respuesta aceptada es realmente peligrosa porque tiene una condición de carrera. Sin embargo, es más simple, por lo que si desconoce la condición de la carrera, o cree que no se aplicará a usted, esa sería su primera elección obvia.
Heikki Toivonen
15
Elevar la excepción solo cuando exception.errno != errno.EEXISTignore involuntariamente el caso cuando la ruta existe pero es un objeto que no es un directorio, como un archivo. La excepción idealmente debería plantearse si la ruta es un objeto que no es de directorio.
Acumenus
178
Tenga en cuenta que el código anterior es equivalente aos.makedirs(path,exist_ok=True)
Navin
58
@Navin El exist_okparámetro se introdujo en Python 3.2. No está presente en Python 2.x. Lo incorporaré en mi respuesta.
Acumenus
26
@HeikkiToivonen Técnicamente hablando, si otro programa está modificando los directorios y archivos al mismo tiempo que su programa, todo su programa es una condición de carrera gigante. ¿Qué impide que otro programa simplemente elimine este directorio después de que el código lo crea y antes de que realmente coloque archivos en él?
jpmc26
102

Yo personalmente recomendaría que utilices os.path.isdir()para probar en lugar 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

Si usted tiene:

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

Y una entrada tonta del usuario:

:: /tmp/dirname/filename.etc

... Vas a terminar con un directorio llamado filename.etccuando pasas ese argumento os.makedirs()si pruebas con os.path.exists().

Peter Mortensen
fuente
8
Si usa solo 'isdir', ¿no seguirá teniendo problemas cuando intente crear el directorio y ya exista un archivo con el mismo nombre?
MrWonderful
3
@MrWonderful La excepción resultante al crear un directorio sobre un archivo existente reflejaría correctamente el problema a la persona que llama.
Damian Yerrick
79

Verifique os.makedirs: (Se asegura de que exista la ruta completa).
Para manejar el hecho de que el directorio podría existir, capture OSError. (Si exist_okes False(el valor predeterminado), OSErrorse genera un si el directorio de destino ya existe).

import os
try:
    os.makedirs('./path/to/somewhere')
except OSError:
    pass
Douglas Mayle
fuente
19
con el try / except, se le enmascarar errores en la creación del directorio, en el caso en que no existe el directorio, pero por alguna razón no puede hacerlo
Blair Conrad
3
OSErroraparecerá aquí si la ruta es un archivo o directorio existente. He publicado una respuesta para abordar esto.
Acumenus
44
Esto está a medio camino. Es necesario verificar la condición de sub-error OSErrorantes de decidir ignorarlo. Ver stackoverflow.com/a/5032238/763269 .
Chris Johnson
71

A partir de Python 3.5, pathlib.Path.mkdirtiene una exist_okbandera:

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

Esto crea recursivamente el directorio y no genera una excepción si el directorio ya existe.

(así como os.makedirsobtuve una exist_okbandera a partir de Python 3.2, por ejemplo os.makedirs(path, exist_ok=True))

protagonista de hiro
fuente
46

Percepciones sobre los detalles de esta situación.

Usted proporciona un archivo en particular en una ruta determinada y extrae el directorio de la ruta del archivo. Luego, después de asegurarse de tener el directorio, intenta abrir un archivo para leerlo. Para comentar sobre este código:

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

Queremos evitar la sobreescritura de la función interna, dir. Además, filepatho tal vez fullfilepathsea ​​probablemente un nombre semántico mejor que filenameeste, así estaría mejor escrito:

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

Su objetivo final es abrir este archivo, inicialmente declara, para escribir, pero esencialmente se está acercando a este objetivo (basado en su código) de esta manera, que abre el archivo para leer :

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

Asumiendo apertura para la lectura

¿Por qué haría un directorio para un archivo que espera que esté allí y pueda leer?

Solo intenta abrir el archivo.

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

Si el directorio o el archivo no está allí, obtendrá un IOErrornúmero de error asociado: errno.ENOENTapuntará al número de error correcto independientemente de su plataforma. Puedes atraparlo si quieres, por ejemplo:

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

Asumiendo que estamos abriendo para escribir

Esto es probablemente lo que quieres.

En este caso, probablemente no enfrentamos ninguna condición de carrera. Así que haz lo que eras, pero ten en cuenta que para escribir, debes abrir con el wmodo (o aagregar). También es una mejor práctica de Python utilizar el administrador de contexto para abrir archivos.

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

Sin embargo, supongamos que tenemos varios procesos de Python que intentan poner todos sus datos en el mismo directorio. Entonces podemos tener una disputa sobre la creación del directorio. En ese caso, es mejor envolver la makedirsllamada en un bloque 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)
Aaron Hall
fuente
34

Prueba la os.path.existsfunción

if not os.path.exists(dir):
    os.mkdir(dir)
ido
fuente
3
Iba a comentar sobre la pregunta, pero ¿nos referimos a os.mkdir? Mi python (2.5.2) no tiene os.path.mkdir ....
Blair Conrad
1
No hay os.path.mkdir()método El módulo os.path implementa algunas funciones útiles en los nombres de ruta .
Serge S.
31

He puesto lo siguiente abajo. Sin embargo, no es totalmente infalible.

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

Ahora, como digo, esto no es realmente infalible, porque tenemos la posibilidad de no poder crear el directorio, y otro proceso de creación durante ese período.

Ali Afshar
fuente
Dos problemas: (1) necesita verificar la condición de sub-error de OSError antes de decidirse a verificar os.path.exists, consulte stackoverflow.com/a/5032238/763269, y (2) el éxito os.path.existsno significa que el directorio existe, solo que la ruta existe: podría ser un archivo, un enlace simbólico u otro objeto del sistema de archivos.
Chris Johnson
24

¿Comprobar si existe un directorio y crearlo si es necesario?

La respuesta directa a esto es, suponiendo una situación simple en la que no esperes que otros usuarios o procesos estén jugando con tu directorio:

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

o si hacer el directorio está sujeto a condiciones de carrera (es decir, si después de verificar que la ruta existe, es posible que ya haya hecho algo más) haga esto:

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

Pero quizás un enfoque aún mejor es eludir el problema de contención de recursos, utilizando directorios temporales a través de tempfile:

import tempfile

d = tempfile.mkdtemp()

Aquí están los elementos esenciales del documento en línea:

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.

Nuevo en Python 3.5: pathlib.Pathconexist_ok

Hay un nuevo Pathobjeto (a partir de 3.4) con muchos métodos que uno desearía usar con rutas, uno de los cuales es mkdir.

(Por contexto, estoy rastreando mi representante semanal con un script. Aquí están las partes relevantes del código del script que me permiten evitar golpear Stack Overflow más de una vez al día por los mismos datos).

Primero las importaciones relevantes:

from pathlib import Path
import tempfile

No tenemos que lidiar os.path.joinahora, solo une las partes del camino con /:

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

Luego, me aseguro de que el directorio exista, el exist_okargumento se muestra en Python 3.5:

directory.mkdir(exist_ok=True)

Aquí está la parte relevante de la documentación :

Si exist_okes verdadero, FileExistsErrorse ignorarán las excepciones (el mismo comportamiento que el POSIX mkdir -pcomando), pero solo si el último componente de la ruta no es un archivo no directorio existente.

Aquí hay un poco más del script: en mi caso, no estoy sujeto a una condición de carrera, solo tengo un proceso que espera que el directorio (o archivos contenidos) esté allí, y no tengo nada que intente eliminar El directorio.

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

Pathlos objetos deben ser forzados strantes de que otras API que esperan strrutas puedan usarlos.

Tal vez pandas debe actualizarse para aceptar instancias de la clase base abstracta, os.PathLike.

Aaron Hall
fuente
20

En Python 3.4 también puede usar el nuevo 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
fuente
@JanuszSkonieczny pypi.python.org/pypi/pathlib2 es el nuevo backport. El más viejo está sin mantenimiento.
Acumenus
Como se indica en la primera línea del archivo Léame; P. Pero el antiguo backport sigue siendo válido para la respuesta aquí. Y no hay dolor de cabeza para nombrar. No es necesario explicar por qué y cuándo usar pathliby dónde pathlib2para los nuevos usuarios, y creo que los profesionales aquí descubrirán la depreciación;)
Janusz Skonieczny
13

La documentación relevante de Python sugiere el uso del estilo de codificación EAFP (más fácil pedir perdón que permiso) . Esto significa que el 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

es mejor que la alternativa

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

La documentación sugiere esto exactamente debido a la condición de carrera discutida en esta pregunta. Además, como otros mencionan aquí, existe una ventaja de rendimiento al consultar una vez en lugar del doble del sistema operativo. Finalmente, el argumento presentado, potencialmente, a favor del segundo código en algunos casos, cuando el desarrollador conoce el entorno en el que se ejecuta la aplicación, solo se puede defender en el caso especial de que el programa haya establecido un entorno privado para en sí (y otras instancias del mismo programa).

Incluso en ese caso, esta es una mala práctica y puede conducir a una depuración inútil durante mucho tiempo. Por ejemplo, el hecho de que establezcamos los permisos para un directorio no debería dejarnos con la impresión de que los permisos están configurados adecuadamente para nuestros propósitos. Un directorio padre podría montarse con otros permisos. En general, un programa siempre debe funcionar correctamente y el programador no debe esperar un entorno específico.

kavadias
fuente
12

En Python3 , os.makedirsadmite la configuración exist_ok. La configuración predeterminada es False, lo que significa OSErrorque se generará un si el directorio de destino ya existe. Al establecer exist_oken True, OSError(el directorio existe) se ignorará y el directorio no se creará.

os.makedirs(path,exist_ok=True)

En Python2 , os.makedirsno admite la configuración exist_ok. Puede usar el enfoque en la respuesta 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
fuente
11

Para una solución de una línea, puede usar IPython.utils.path.ensure_dir_exists():

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

De la documentación : asegúrese de que exista un directorio. Si no existe, intente crearlo y protegerse contra una condición de carrera si otro proceso está haciendo lo mismo.

tashuhka
fuente
Nueva documentación de IPython disponible aquí .
jkdev
3
El IPythonmódulo de ninguna manera está garantizado para estar presente. Está presente de forma nativa en mi Mac, pero no en ninguna de mis instalaciones de Linux de Python. Básicamente, no es uno de los módulos enumerados en el índice del módulo Python .
Acumenus
1
Por supuesto. Con el fin de instalar el paquete, basta con ejecutar la costumbre pip install ipythono incluir la dependencia en su requirements.txt o pom.xml . Documentación: ipython.org/install.html
tashuhka
9

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

Tenga en cuenta que también creará los directorios ancestrales.

Funciona para Python 2 y 3.

Dennis Golomazov
fuente
2
distutils.dir_utilno forma parte de la API pública distutil y tiene problemas en entornos de subprocesos múltiples: bugs.python.org/issue10948
Pod
1
Si. Como se señaló en el primer mensaje del error, el problema distutils.dir_util.mkpathes que si crea un directorio, luego lo elimina de dentro o fuera de Python, luego mkpathvuelva a usarlo , mkpathsimplemente usará su información en caché no válida de haber creado previamente el directorio, y En realidad, no hacer el directorio de nuevo. Por el contrario, os.makedirsno se basa en tal caché.
Acumenus
8

Yo uso os.path.exists(), aquí hay un script de Python 3 que puede usarse para verificar si existe un directorio, crear uno si no existe y eliminarlo si existe (si lo desea).

Solicita a los usuarios la entrada del directorio y puede modificarse fácilmente.

Michael Strobel
fuente
6

Puedes usar os.listdirpara esto:

import os
if 'dirName' in os.listdir('parentFolderPath')
    print('Directory Exists')
iPhynx
fuente
Esto no responde la pregunta
Georgy
6

Encontré este Q / A y al principio me sorprendieron algunas de las fallas y errores que estaba recibiendo. Estoy trabajando en Python 3 (v.3.5 en un entorno virtual de Anaconda en un sistema Arch Linux x86_64).

Considere esta estructura de directorio:

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

Aquí están mis experimentos / notas, que aclaran las cosas:

# ----------------------------------------------------------------------------
# [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
# ----------------------------------------------------------------------------

Conclusión: en mi opinión, el "Método 2" es más robusto.

[1] ¿Cómo puedo crear un directorio si no existe?

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

Victoria Stuart
fuente
6

Vi las respuestas de Heikki Toivonen y ABB y pensé en esta variación.

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
fuente
6

Use este comando check y cree dir

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

¿Por qué no usar el módulo de subproceso si se ejecuta en una máquina que admite comandos mkdircon -popción? Funciona en python 2.7 y python 3.6

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

Debería hacer el truco en la mayoría de los sistemas.

En situaciones en las que la portabilidad no importa (por ejemplo, usando Docker), la solución es limpiar 2 líneas. Tampoco tiene que agregar lógica para verificar si existen directorios o no. Finalmente, es seguro volver a ejecutar sin efectos secundarios.

Si necesita manejo de errores:

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

Si considera lo siguiente:

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

significa que existe un directorio (ruta) Y es un directorio. Entonces para mí de esta manera hace lo que necesito. Entonces puedo asegurarme de que sea una carpeta (no un archivo) y que exista.

Ralph Schwerdt
fuente
¿Cómo responde esto a la pregunta de crear un directorio?
Georgy
3

Llame a la función create_dir()en el punto de entrada de su programa / proyecto.

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
fuente
3

Debe establecer la ruta completa antes de crear el directorio:

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)

Esto funciona para mí y, con suerte, también funcionará para ti

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

Donde su código aquí es use el comando (táctil)

Esto verificará si el archivo está allí, si no lo está, lo creará.

El mal existe
fuente