2010-02-13 17 views
152

¿Cuál es la forma preferida de comprobar si existe un archivo y si no crearlo?¿Manera pitónica de verificar si existe un archivo?

+1

real duplicado pregunta: [crear un archivo de forma segura si y sólo si no existe con el pitón] (http://stackoverflow.com/q/10978869/3345375). En Python 3.3+, use el indicador 'x' cuando ['open()'] (https://docs.python.org/3/library/functions.html#open) ing en un archivo para evitar condiciones de carrera. – jkdev

Respuesta

237

Para comprobar si un camino es un archivo existente:

os.path.isfile(path)

Volver True si ruta es un archivo normal existente. Esto sigue los enlaces simbólicos , por lo tanto islink() y isfile() pueden ser verdaderos para la misma ruta .

+10

Por supuesto, puede entrar en una condición de carrera donde el archivo no existe cuando lo marca, pero surge antes de que pueda crearlo. Extremadamente improbable, pero posible. –

+0

Esto devolverá verdadero si existe un directorio por el nombre de pila, en cuyo caso fallará una creación posterior del archivo. –

+13

Creo que estás pensando en os.path.exists, que devuelve True si la ruta existe (es decir, es un archivo o un directorio). Como se muestra arriba, os.path.isfile devuelve True cuando la ruta es un archivo normal. – chradcliffe

11

Si (cuando no existe el archivo) que desea crear como vacío, lo más sencillo es

with open(thepath, 'a'): pass 

(en Python 2.6 o mejor, en 2,5, esto requiere una "importación del futuro "en la parte superior de su módulo).

Si, por otro lado, desea dejar el archivo solo si existe, pero ponga contenido no vacío específico allí, de lo contrario, los enfoques más complicados basados ​​en if os.path.isfile(thepath):/else bloques de instrucciones son probablemente más adecuados.

+0

open() no es una solución ideal en comparación con os.isfile. Abrir realiza acciones innecesarias si solo desea verificar la existencia del archivo (aunque es cierto, abrir es la mejor manera de leer y escribir archivos) y requiere privilegios de lectura del archivo para verificar la existencia del archivo. –

68

En lugar de os.path.isfile, sugerido por otros, sugiero usar os.path.exists, que busca cualquier cosa con ese nombre, no solo si se trata de un archivo normal.

Por lo tanto:

if not os.path.exists(filename): 
    file(filename, 'w').close() 

alternativa:

file(filename, 'w+').close() 

Este último será crear el archivo si existe, pero no de otra manera. Sin embargo, fallará si el archivo existe, pero no tiene permiso para escribir en él. Es por eso que prefiero la primera solución.

+0

Para Python 3 necesita reemplazar 'archivo' con' abrir': 'si no os.path.exists (filename): abrir (nombre de archivo," w + ") cerrar()' – Abhijeet

+0

¿Quiso decir? " Este último creará el archivo si no existe. "? – MarredCheese

+0

Tenga en cuenta que 'archivo (nombre de archivo, 'w +'). Close()' [truncará el archivo si existe] (https://docs.python.org/2/library/functions.html#open). – johndodo

32

Me parece que todas las otras respuestas aquí (hasta ahora) no abordan la condición de carrera que ocurre con sus soluciones propuestas.

Cualquier código donde primero compruebe la existencia de archivos, y luego, algunas líneas más adelante en su programa, lo crea, corre el riesgo de que el archivo se cree mientras no miraba y le causaba problemas (o usted está causando el problema del propietario de "ese otro archivo").

Si se quiere evitar este tipo de cosas, sugeriría algo como lo siguiente (no probado):

import os 

def open_if_not_exists(filename): 
    try: 
     fd = os.open(filename, os.O_CREAT | os.O_EXCL | os.O_WRONLY) 
    except OSError, e: 
     if e.errno == 17: 
      print e 
      return None 
     else: 
      raise 
    else: 
     return os.fdopen(fd, 'w') 

Esto debería abrir el archivo para escritura si no existe ya, y devolver una archivo-objeto. Si existe, imprimirá "Ooops" y devolverá None (no probado, y basado únicamente en la lectura the python documentation, por lo que podría no ser 100% correcto).

+2

Esto funciona, pero 'fobj = os.fdopen (fd)' debe ser 'fobj = os.fdopen (ds, 'w')' y luego 'os.close (fd)'. – NebulaFox

+0

Opps, rayar 'os.close (fd)' – NebulaFox

+1

En realidad, la línea necesita ser 'fobj = os.fdopen (fd, 'w')'. Eso es 'fd' no 'ds' –

-1

Esta fue la mejor manera para mí. Puede recuperar todos los archivos existentes (ya sean enlaces simbólicos o normales):

os.path.lexists (ruta)

Return True if path refers to an existing path. Returns True for broken symbolic links. Equivalent to exists() on platforms lacking os.lstat(). 

New in version 2.4. 
Cuestiones relacionadas