¿Cuál es la forma más elegante de comprobar 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 he intentado:
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, me perdí 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 ocurra automáticamente?
Veo dos respuestas con buenas cualidades, cada una con un pequeño defecto, así que daré mi opinión al respecto:
Prueba os.path.exists
, y considera os.makedirs
para la creación.
import os
if not os.path.exists(directory):
os.makedirs(directory)
Como se ha señalado en los comentarios y en otros lugares, hay una condición de carrera – si el directorio se crea entre las llamadas os.path.exists
y os.makedirs
, os.makedirs
fallará con un OSError
. Desgraciadamente, el hecho de que se detecte un OSError
y se continúe no es infalible, ya que se ignorará un fallo en la creación del directorio debido a otros factores, como permisos insuficientes, disco lleno, etc.
Una opción sería atrapar el OSError
y examinar el código de error incrustado (ver Existe una forma 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 comprobación, y luego lo eliminó antes de la segunda – todavía podríamos ser engañados.
Dependiendo de la aplicación, el peligro de las operaciones concurrentes puede ser mayor o menor que el peligro que suponen otros factores como los permisos de los archivos. El desarrollador tendría que saber más sobre la aplicación concreta que está desarrollando y su entorno previsto 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 permitiendo un argumento de palabra clave para os.makedirs
llamado exist_ok
(en 3.2+).
os.makedirs("path/to/directory", exist_ok=True) # succeeds even if directory exists.
Comprueba os.makedirs
: (Se asegura de que la ruta completa existe).
Para manejar el hecho de que el directorio podría existir, captura OSError
.
(Si exist_ok
es False
(el valor por defecto), se genera un OSError
si el directorio de destino ya existe).
import os
try:
os.makedirs('./path/to/somewhere')
except OSError:
pass
Prueba la función os.path.exists
if not os.path.exists(dir):
os.mkdir(dir)