python manejo - ¿Cómo verifico si un archivo existe sin excepciones?




una cambiar (25)

¿Cómo veo si un archivo existe o no, sin usar la declaración de try ?


Answers

2017/12/22 :

Aunque casi todas las formas posibles se han incluido en (al menos una de) las respuestas existentes (por ejemplo, se agregaron cosas específicas de Python 3.4 ), intentaré agrupar todo.

Nota : cada pieza del código de la biblioteca estándar de Python que voy a publicar pertenece a la versión 3.5.3 (las citas de los documentos son específicas de la versión 3 ).

Enunciado del problema :

  1. Comprobar archivo ( argumentable : también carpeta (archivo "especial")? Existencia
  2. No use los bloques try / except / else / finally

Posibles soluciones :

  1. [Python]: os.path. existe ( ruta ) (también verifique otros miembros de la familia de funciones como os.path.isfile , os.path.isdir , os.path.lexists para ver comportamientos ligeramente diferentes)

    os.path.exists(path)
    

    Devuelva True si la ruta se refiere a una ruta existente o un descriptor de archivo abierto. Devuelve False para enlaces simbólicos rotos. En algunas plataformas, esta función puede devolver False si no se concede el permiso para ejecutar os.stat() en el archivo solicitado, incluso si la ruta existe físicamente.

    Todo bien, pero si siguiendo el árbol de importación:

    • os.path - posixpath.py ( ntpath.py )

      • genericpath.py , línea ~ # 20 +

        def exists(path):
            """Test whether a path exists.  Returns False for broken symbolic links"""
            try:
                st = os.stat(path)
            except os.error:
                return False
            return True
        

    es solo un bloque try/except around os.stat() os.stat() . Por lo tanto, su código es try/except free, pero más abajo en el frameestack hay (al menos) uno de estos bloques. Esto también se aplica a otras funciones ( incluido os.path.isfile ).

    1.1. [Python]: pathlib.Path. is_file ()

    • Es una forma más elegante (y más de python ic) de manejar caminos, pero
    • Bajo el capó, hace exactamente lo mismo ( pathlib.py , línea ~ # 1330 ):

      def is_file(self):
          """
          Whether this path is a regular file (also True for symlinks pointing
          to regular files).
          """
          try:
              return S_ISREG(self.stat().st_mode)
          except OSError as e:
              if e.errno not in (ENOENT, ENOTDIR):
                  raise
              # Path doesn't exist or is a broken symlink
              # (see https://bitbucket.org/pitrou/pathlib/issue/12/)
              return False
      
  2. [Python]: Con los administradores de contexto de declaración . Ya sea:

    • Crea uno:

      class Swallow:  # Dummy example
          swallowed_exceptions = (FileNotFoundError,)
      
          def __enter__(self):
              print("Entering...")
      
          def __exit__(self, exc_type, exc_value, exc_traceback):
              print("Exiting:", exc_type, exc_value, exc_traceback)
              return exc_type in Swallow.swallowed_exceptions  # only swallow FileNotFoundError (not e.g. TypeError - if the user passes a wrong argument like None or float or ...)
      
      • Y su uso: replicaré el comportamiento de isfile (tenga en cuenta que esto es solo para fines de demostración, no intente escribir dicho código para la producción ):

        import os
        import stat
        
        
        def isfile_seaman(path):  # Dummy func
            result = False
            with Swallow():
                result = stat.S_ISREG(os.stat(path).st_mode)
            return result
        
    • Utilice [Python]: contextlib. suprimir ( * excepciones ) - que fue diseñado específicamente para suprimir selectivamente excepciones


    Pero, parecen ser envoltorios sobre bloques try/except/else/finally , como [Python]: los estados de with :

    Esto permite un try común ... except ... finally los patrones de uso se encapsulan para una reutilización conveniente.

  3. Funciones transversales del sistema de archivos (y busque en los resultados elementos coincidentes)


    Dado que estas iteraciones sobre carpetas (en la mayoría de los casos) son ineficientes para nuestro problema (hay excepciones, como glob bing sin comodines, como lo señaló @ShadowRanger), así que no voy a insistir en ellas. Sin mencionar que, en algunos casos, puede ser necesario el procesamiento del nombre de archivo.

  4. [Python]: os. acceso ( ruta, modo, *, dir_fd = Ninguna, Effective_ids = False, follow_symlinks = True ) cuyo comportamiento es cercano a os.path.exists (en realidad es más amplio, principalmente debido al segundo argumento)

    • los permisos de los usuarios pueden restringir la "visibilidad" del archivo, como indica el documento:

      ... prueba si el usuario que invoca tiene el acceso especificado a la ruta . el modo debe ser F_OK para probar la existencia de ruta ...

    os.access("/tmp", os.F_OK)
    

    Como también trabajo en C , también utilizo este método porque bajo el capó, llama API s nativas (de nuevo, a través de "$ {PYTHON_SRC_DIR} /Modules/posixmodule.c" ), pero también abre una puerta para un posible usuario. errores , y no es tan Python ic como otras variantes. Así que, como bien señaló @AaronHall, no lo use a menos que sepa lo que está haciendo:

    Nota : llamar a API nativas también es posible a través de [Python]: ctypes - Una biblioteca de funciones extrañas para Python , pero en la mayoría de los casos es más complicada.

    ( Ganancia específica): dado que msvcr * ( vcruntime * ) también exporta una familia [MSDN]: _access, _waccess function, aquí hay un ejemplo:

    Python 3.5.3 (v3.5.3:1880cb95a742, Jan 16 2017, 16:02:32) [MSC v.1900 64 bit (AMD64)] on win32
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import os, ctypes
    >>> ctypes.CDLL("msvcrt")._waccess(u"C:\\Windows\\System32\\cmd.exe", os.F_OK)
    0
    >>> ctypes.CDLL("msvcrt")._waccess(u"C:\\Windows\\System32\\___cmd.exe", os.F_OK)
    -1
    

    Notas :

    • Aunque no es una buena práctica, estoy usando os.F_OK en la llamada, pero eso es solo por claridad (su valor es 0 )
    • Estoy usando _waccess para que el mismo código funcione en Python3 y Python2 (a pesar de las diferencias relacionadas con Unicode entre ellos)
    • Aunque esto se dirige a un área muy específica, no se mencionó en ninguna de las respuestas anteriores.


    La contraparte Lnx ( Ubtu (16 x64) ) también:

    Python 3.5.2 (default, Nov 17 2016, 17:05:23)
    [GCC 5.4.0 20160609] on linux
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import os, ctypes
    >>> ctypes.CDLL("/lib/x86_64-linux-gnu/libc.so.6").access(b"/tmp", os.F_OK)
    0
    >>> ctypes.CDLL("/lib/x86_64-linux-gnu/libc.so.6").access(b"/tmp1", os.F_OK)
    -1
    

    Notas :

    • En su lugar, codifique la ruta de acceso de libc ( "/lib/x86_64-linux-gnu/libc.so.6" ) que puede (y, muy probablemente,) variará entre los sistemas, None (o la cadena vacía) se puede pasar al constructor de CDLL ( ctypes.CDLL(None).access(b"/tmp", os.F_OK) ). Según [hombre]: DLOPEN (3) :

      Si el nombre de archivo es NULL, el identificador devuelto es para el programa principal. Cuando se le da a dlsym (), este identificador provoca una búsqueda de un símbolo en el programa principal, seguido de todos los objetos compartidos cargados al inicio del programa, y ​​luego todos los objetos compartidos cargados por dlopen () con el indicador RTLD_GLOBAL .

      • El programa principal (actual) ( python ) está vinculado contra libc , por lo que sus símbolos (incluido el access ) se cargarán
      • Esto debe manejarse con cuidado, ya que funciones como main , Py_Main y (todas) están disponibles; llamarlos podría tener efectos desastrosos (en el programa actual)
      • Esto no se aplica también a Win (pero eso no es tan importante, ya que msvcrt.dll se encuentra en "% SystemRoot% \ System32" que está en % PATH% de forma predeterminada). Quería ir más allá y replicar este comportamiento en Win (y enviar un parche), pero resulta que, [MSDN]: la función GetProcAddress solo "ve" los símbolos exportados , así que a menos que alguien declare las funciones en el ejecutable principal como __declspec(dllexport) (¿por qué en la Tierra la persona normal haría eso?), el programa principal es cargable pero prácticamente inutilizable
  5. Instalar algunos módulos de terceros con capacidades de sistema de archivos

    Lo más probable es que dependa de una de las formas anteriores (tal vez con personalizaciones leves).
    Un ejemplo sería (de nuevo, específico para Win ) [GitHub]: Python para Windows (pywin32) Extensions , que es un contenedor de Python sobre WINAPI s.

    Pero, ya que esto es más como una solución, me detengo aquí.

  6. Otra solución (lame) ( gainarie ) es (como me gusta llamarlo), el enfoque de administrador de sistemas : usar Python como un contenedor para ejecutar comandos de shell

    • Ganar :

      (py35x64_test) e:\Work\Dev\StackOverflow\q000082831>"e:\Work\Dev\VEnvs\py35x64_test\Scripts\python.exe" -c "import os; print(os.system('dir /b \"C:\\Windows\\System32\\cmd.exe\" > nul 2>&1'))"
      0
      
      (py35x64_test) e:\Work\Dev\StackOverflow\q000082831>"e:\Work\Dev\VEnvs\py35x64_test\Scripts\python.exe" -c "import os; print(os.system('dir /b \"C:\\Windows\\System32\\cmd.exe.notexist\" > nul 2>&1'))"
      1
      
    • Lnx ( Ubtu ):

      [[email protected]:~]> python3 -c "import os; print(os.system('ls \"/tmp\" > /dev/null 2>&1'))"
      0
      [[email protected]:~]> python3 -c "import os; print(os.system('ls \"/tmp.notexist\" > /dev/null 2>&1'))"
      512
      

Línea inferior

  • Use los bloques try / except / else / finally , porque pueden evitar que se tope con una serie de problemas desagradables. Un contra-ejemplo en el que puedo pensar es en el rendimiento: tales bloques son costosos, así que trate de no colocarlos en el código que se supone que debe ejecutarse cientos de miles de veces por segundo (pero dado que (en la mayoría de los casos) implica acceso al disco, no será el caso).

Nota final (es) :

  • Intentaré mantenerlo actualizado, cualquier sugerencia es bienvenida, incorporaré cualquier cosa útil que surja en la respuesta.

No parece que haya una diferencia funcional significativa entre try / except y isfile() , por lo que deberías usar cuál tiene sentido.

Si quieres leer un archivo, si existe, hazlo

try:
    f = open(filepath)
except IOError:
    print 'Oh dear.'

Pero si solo desea cambiar el nombre de un archivo si existe, y por lo tanto no necesita abrirlo,

if os.path.isfile(filepath):
    os.rename(filepath, filepath + '.old')

Si desea escribir en un archivo, si no existe, haga

# python 2
if not os.path.isfile(filepath):
    f = open(filepath, 'w')

# python 3, x opens for exclusive creation, failing if the file already exists
try:
    f = open(filepath, 'wx')
except IOError:
    print 'file already exists'

Si necesita bloqueo de archivos, eso es un asunto diferente.


Si la razón por la que estás verificando es para poder hacer algo como if file_exists: open_it() , es más seguro try alrededor del intento de abrirlo. Al verificar y luego abrir, se corre el riesgo de que el archivo se elimine o se mueva, o algo así cuando se comprueba y cuando se intenta abrir.

Si no planea abrir el archivo inmediatamente, puede usar os.path.isfile

Devuelva True si la ruta es un archivo regular existente. Esto sigue a los enlaces simbólicos, por lo que tanto islink() como os.path.isfile pueden ser verdaderos para la misma ruta.

import os.path
os.path.isfile(fname) 

Si necesitas estar seguro de que es un archivo.

Comenzando con Python 3.4, el módulo pathlib ofrece un enfoque orientado a objetos (backported a pathlib2 en Python 2.7):

from pathlib import Path

my_file = Path("/path/to/file")
if my_file.is_file():
    # file exists

Para verificar un directorio, haga:

if my_file.is_dir():
    # directory exists

Para verificar si un objeto de Path existe independientemente de si se trata de un archivo o directorio, use exists() :

if my_file.exists():
    # path exists

También puedes usar resolve() en un bloque try :

try:
    my_abs_path = my_file.resolve()
except FileNotFoundError:
    # doesn't exist
else:
    # exists

Aquí hay un comando de 1 línea de Python para el entorno de línea de comandos de Linux. Encuentro esto MUY BUENO ya que no soy un tipo Bash tan caliente.

python -c "import os.path; print os.path.isfile('/path_to/file.xxx')"

Espero que esto sea útil.


Revisar archivo o directorio existe

Puedes seguir estas tres formas:

Nota 1: El os.path.isfileusado solo para archivos.

import os.path
os.path.isfile(filename) # True if file exists
os.path.isfile(dirname) # False if directory exists

Nota 2: El os.path.existsusado tanto para archivos como para directorios.

import os.path
os.path.exists(filename) # True if file exists
os.path.exists(dirname) #True if directory exists

El pathlib.Pathmétodo (incluido en Python 3+, instalable con pip para Python 2)

from pathlib import Path
Path(filename).exists()

¿Cómo verifico si existe un archivo, usando Python, sin usar una declaración de prueba?

Ahora disponible desde Python 3.4, importe y cree una instancia de un objeto de Path con el nombre del archivo, y verifique el método is_file (tenga en cuenta que esto devuelve True para los enlaces simbólicos que también apuntan a archivos normales):

>>> from pathlib import Path
>>> Path('/').is_file()
False
>>> Path('/initrd.img').is_file()
True
>>> Path('/doesnotexist').is_file()
False

Si estás en Python 2, puedes realizar una backport del módulo pathlib desde pypi, pathlib2 o, de lo contrario, verificar isfile desde el módulo os.path :

>>> import os
>>> os.path.isfile('/')
False
>>> os.path.isfile('/initrd.img')
True
>>> os.path.isfile('/doesnotexist')
False

Ahora, lo anterior es probablemente la mejor respuesta directa pragmática aquí, pero existe la posibilidad de una condición de carrera (dependiendo de lo que intenta lograr) y el hecho de que la implementación subyacente usa un try , pero los usos de Python lo try en todas partes. implementación.

Debido a que los usos de Python try todas partes, realmente no hay razón para evitar una implementación que lo use.

Pero el resto de esta respuesta intenta considerar estas advertencias.

Respuesta más larga, mucho más pedante.

Disponible desde Python 3.4, use el nuevo objeto Path en pathlib . Tenga en cuenta que .exists no es del todo correcto, porque los directorios no son archivos (excepto en el sentido de UNIX que todo es un archivo).

>>> from pathlib import Path
>>> root = Path('/')
>>> root.exists()
True

Así que necesitamos usar is_file :

>>> root.is_file()
False

Aquí está la ayuda en is_file :

is_file(self)
    Whether this path is a regular file (also True for symlinks pointing
    to regular files).

Así que vamos a obtener un archivo que sabemos que es un archivo:

>>> import tempfile
>>> file = tempfile.NamedTemporaryFile()
>>> filepathobj = Path(file.name)
>>> filepathobj.is_file()
True
>>> filepathobj.exists()
True

De forma predeterminada, NamedTemporaryFile elimina el archivo cuando está cerrado (y se cerrará automáticamente cuando no haya más referencias a él).

>>> del file
>>> filepathobj.exists()
False
>>> filepathobj.is_file()
False

Sin embargo, si profundiza en la implementación , verá que is_file usa try :

def is_file(self):
    """
    Whether this path is a regular file (also True for symlinks pointing
    to regular files).
    """
    try:
        return S_ISREG(self.stat().st_mode)
    except OSError as e:
        if e.errno not in (ENOENT, ENOTDIR):
            raise
        # Path doesn't exist or is a broken symlink
        # (see https://bitbucket.org/pitrou/pathlib/issue/12/)
        return False

Condiciones de carrera: ¿Por qué nos gusta probar?

Nos gusta try porque evita condiciones de carrera. Con el try , simplemente intenta leer su archivo, esperando que esté allí, y si no, puede detectar la excepción y realizar cualquier comportamiento de recuperación que tenga sentido.

Si desea verificar que un archivo existe antes de intentar leerlo, y puede estar eliminándolo y luego puede estar usando varios subprocesos o procesos, u otro programa conoce ese archivo y podría eliminarlo, corre el riesgo de una condición de carrera si verifica que existe, porque entonces está compitiendo para abrirla antes de que cambie su condición (su existencia).

Las condiciones de la carrera son muy difíciles de depurar porque hay una ventana muy pequeña en la que pueden hacer que tu programa falle.

Pero si esta es su motivación, puede obtener el valor de una declaración de try utilizando el administrador de contexto de suppress .

Evitar las condiciones de carrera sin una declaración de prueba: suppress

Python 3.4 nos proporciona el administrador de contexto de suppress (anteriormente el administrador de contexto de ignore ), que hace exactamente lo mismo en forma semántica en menos líneas, mientras que también (al menos superficialmente) cumple con la solicitud original para evitar una declaración de try :

from contextlib import suppress
from pathlib import Path

Uso:

>>> with suppress(OSError), Path('doesnotexist').open() as f:
...     for line in f:
...         print(line)
... 
>>>
>>> with suppress(OSError):
...     Path('doesnotexist').unlink()
... 
>>> 

Para los Pythons anteriores, puedes rodar tu propia suppress , pero sin un try será más detallado que con. Creo que en realidad esta es la única respuesta que no usa try en ningún nivel de Python que se pueda aplicar antes de Python 3.4 porque usa un administrador de contexto en su lugar:

class suppress(object):
    def __init__(self, *exceptions):
        self.exceptions = exceptions
    def __enter__(self):
        return self
    def __exit__(self, exc_type, exc_value, traceback):
        if exc_type is not None:
            return issubclass(exc_type, self.exceptions)

Quizás más fácil con un intento:

from contextlib import contextmanager

@contextmanager
def suppress(*exceptions):
    try:
        yield
    except exceptions:
        pass

Otras opciones que no cumplen con la solicitud de "sin intentarlo":

isfile

import os
os.path.isfile(path)

de los docs :

os.path.isfile(path)

Devuelva True si la ruta es un archivo regular existente. Esto sigue a los enlaces simbólicos, por lo que tanto islink() como isfile() pueden ser verdaderos para la misma ruta.

Pero si examinas el source de esta función, verás que realmente usa una declaración de prueba:

# This follows symbolic links, so both islink() and isdir() can be true
# for the same path on systems that support symlinks
def isfile(path):
    """Test whether a path is a regular file"""
    try:
        st = os.stat(path)
    except os.error:
        return False
    return stat.S_ISREG(st.st_mode)
>>> OSError is os.error
True

Todo lo que hace es usar la ruta dada para ver si puede obtener estadísticas, capturar OSError y luego verificar si es un archivo si no produjo la excepción.

Si pretende hacer algo con el archivo, sugeriría intentarlo directamente con un intento, excepto para evitar una condición de carrera:

try:
    with open(path) as f:
        f.read()
except OSError:
    pass

os.access

Disponible para Unix y Windows es os.access , pero para usarlo debe pasar indicadores, y no distingue entre archivos y directorios. Esto se usa más para probar si el usuario que invoca real tiene acceso en un entorno de privilegios elevados:

import os
os.access(path, os.F_OK)

También sufre los mismos problemas de condición de carrera que isfile . De la docs :

Nota: el uso de access () para verificar si un usuario está autorizado para, por ejemplo, abrir un archivo antes de hacerlo, utilizando open () crea un agujero de seguridad, ya que el usuario podría aprovechar el corto intervalo de tiempo entre la verificación y la apertura del archivo para manipularlo. Es preferible utilizar técnicas de EAFP. Por ejemplo:

if os.access("myfile", os.R_OK):
    with open("myfile") as fp:
        return fp.read()
return "some default data"

está mejor escrito como:

try:
    fp = open("myfile")
except IOError as e:
    if e.errno == errno.EACCES:
        return "some default data"
    # Not a permission error.
    raise
else:
    with fp:
        return fp.read()

Evite utilizar os.access . Es una función de bajo nivel que tiene más oportunidades de error de usuario que los objetos y funciones de nivel superior descritos anteriormente.

Crítica de otra respuesta:

Otra respuesta dice esto sobre os.access :

Personalmente, prefiero este porque bajo el capó, llama API nativas (a través de "$ {PYTHON_SRC_DIR} /Modules/posixmodule.c"), pero también abre una puerta para posibles errores de los usuarios, y no es tan Pythonic como otras variantes. :

Esta respuesta dice que prefiere un método no pitónico, propenso a errores, sin justificación. Parece animar a los usuarios a usar API de bajo nivel sin entenderlos.

También crea un administrador de contexto que, al devolver incondicionalmente True , permite que todas las Excepciones (¡incluyendo KeyboardInterrupt y SystemExit !) SystemExit en silencio, lo que es una buena manera de ocultar errores.

Esto parece alentar a los usuarios a adoptar malas prácticas.


Aunque siempre recomiendo usar tryy exceptdeclaraciones, aquí hay algunas posibilidades para ti (mi favorito personal está usando os.access):

  1. Intenta abrir el archivo:

    Abrir el archivo siempre verificará la existencia del archivo. Puedes hacer una función así:

    def File_Existence(filepath):
        f = open(filepath)
        return True
    

    Si es False, detendrá la ejecución con un IOError u OSError no administrado en versiones posteriores de Python. Para detectar la excepción, debe usar una cláusula de excepción de prueba. Por supuesto, siempre se puede usar una trydeclaración de excepción (" hsandt ") (gracias a hsandt por hacerme pensar):

    def File_Existence(filepath):
        try:
            f = open(filepath)
        except IOError, OSError: # Note OSError is for later versions of Python
            return False
    
        return True
    
  2. Uso os.path.exists(path):

    Esto comprobará la existencia de lo que especifique. Sin embargo, comprueba los archivos y directorios, así que ten cuidado con la forma en que lo usas.

    import os.path
    >>> os.path.exists("this/is/a/directory")
    True
    >>> os.path.exists("this/is/a/file.txt")
    True
    >>> os.path.exists("not/a/directory")
    False
    
  3. Uso os.access(path, mode):

    Esto comprobará si tienes acceso al archivo. Se comprobará los permisos. Sobre la base de la documentación de os.py, al escribir os.F_OK, comprobará la existencia de la ruta. Sin embargo, usar esto creará un agujero de seguridad, ya que alguien puede atacar su archivo usando el tiempo entre la verificación de los permisos y la apertura del archivo. En su lugar, debería ir directamente a abrir el archivo en lugar de verificar sus permisos. ( EAFP vs LBYP ). Si no va a abrir el archivo más tarde y solo está verificando su existencia, puede usar esto.

    De todos modos, aquí:

    >>> import os
    >>> os.access("/is/a/file.txt", os.F_OK)
    True
    

También debo mencionar que hay dos formas en las que no podrá verificar la existencia de un archivo. O bien el tema será permission deniedo no such file or directory. Si encuentra una IOError, establezca IOError as e(como mi primera opción) y luego ingrese print(e.args)para que pueda determinar su problema. ¡Espero que ayude! :)


if os.path.isfile(path_to_file):
    try: 
        open(path_to_file)
            pass
    except IOError as e:
        print "Unable to open file"

El aumento de excepciones se considera un enfoque aceptable y Pythonic para el control de flujo en su programa. Considere el manejo de archivos faltantes con IOErrors. En esta situación, se generará una excepción IOError si el archivo existe pero el usuario no tiene permisos de lectura.

SRC: http://www.pfinn.net/python-check-if-file-exists.html


¿Cómo verifico si existe un archivo, sin usar la instrucción try?

En 2016, esta es posiblemente la forma más fácil de verificar si existe un archivo y si es un archivo:

import os
os.path.isfile('./file.txt')    # Returns True if exists, else False

isfileEn realidad, es solo un método auxiliar que se usa internamente os.staty por stat.S_ISREG(mode)debajo. Este os.states un método de nivel inferior que le proporcionará información detallada sobre archivos, directorios, sockets, buffers y más. Más sobre os.stat aquí

Nota: Sin embargo, este enfoque no bloqueará el archivo de ninguna manera y, por lo tanto, su código puede ser vulnerable a los errores de " tiempo de verificación a tiempo de uso " ( TOCTTOU ).

Por lo tanto, se considera que generar excepciones es un enfoque aceptable y Pythonic para el control de flujo en su programa. Y uno debe considerar el manejo de archivos faltantes con IOErrors, en lugar de ifdeclaraciones ( solo un consejo ).


Puedes escribir la sugerencia de Brian sin el try:.

from contextlib import suppress

with suppress(IOError), open('filename'):
    process()

suppressEs parte de Python 3.4. En versiones anteriores puedes escribir rápidamente tu propia supresión:

from contextlib import contextmanager

@contextmanager
def suppress(*exceptions):
    try:
        yield
    except exceptions:
        pass

Puedes usar la biblioteca "OS" de Python:

>>> import os
>>> os.path.exists("C:\\Users\\####\\Desktop\\test.txt") 
True
>>> os.path.exists("C:\\Users\\####\\Desktop\\test.tx")
False

import os.path

if os.path.isfile(filepath):

Si ha importado NumPy ya para otros fines, entonces no hay necesidad de importar otras bibliotecas como pathlib, os, paths, etc.

import numpy as np
np.DataSource().exists("path/to/your/file")

Esto devolverá verdadero o falso basado en su existencia.


Añadiendo una ligera variación más que no se refleja exactamente en las otras respuestas.

Esto manejará el caso del file_pathser Noneo cadena vacía.

def file_exists(file_path):
    if not file_path:
        return False
    elif not os.path.isfile(file_path):
        return False
    else:
        return True

Añadiendo una variante basada en la sugerencia de Shahbaz

def file_exists(file_path):
    if not file_path:
        return False
    else:
        return os.path.isfile(file_path)

Añadiendo una variante basada en la sugerencia de Peter Wood

def file_exists(file_path):
    return file_path and os.path.isfile(file_path):

Tienes la función os.path.exists :

import os.path
os.path.exists(file_path)

Esto devuelve True tanto para archivos como para directorios, pero puede usar

os.path.isfile(file_path)

para probar si es un archivo específicamente. Sigue los enlaces simbólicos.


Podrías probar esto (más seguro):

try:
    # http://effbot.org/zone/python-with-statement.htm
    # 'with' is safer to open a file
    with open('whatever.txt') as fh:
        # Do something with 'fh'
except IOError as e:
    print("({})".format(e))

La salida sería:

([Errno 2] No existe tal archivo o directorio: 'whatever.txt')

Luego, dependiendo del resultado, su programa puede seguir ejecutándose desde allí o puede codificar para detenerlo si lo desea.


Python 3.4+ tiene un módulo de ruta orientada a objetos: pathlib . Usando este nuevo módulo, puedes verificar si un archivo existe así:

import pathlib
p = pathlib.Path('path/to/file')
if p.is_file():  # or p.is_dir() to see if it is a directory
    # do stuff

Puede (y normalmente debería) seguir usando un bloque try/except al abrir archivos:

try:
    with p.open() as f:
        # do awesome stuff
except OSError:
    print('Well darn.')

El módulo pathlib tiene muchas cosas geniales: prácticas convenientes, verificación del propietario del archivo, una combinación de rutas más fácil, etc. Vale la pena echarle un vistazo. Si estás en una versión anterior de Python (versión 2.6 o posterior), puedes instalar pathlib con pip:

# installs pathlib2 on older Python versions
# the original third-party module, pathlib, is no longer maintained.
pip install pathlib2

Luego importarlo de la siguiente manera:

# Older Python versions
import pathlib2 as pathlib

En 2016, la mejor manera es usar os.path.isfile :

>>> os.path.isfile('/path/to/some/file.txt')

O en Python 3 puedes usar pathlib :

import pathlib
path = pathlib.Path('/path/to/some/file.txt')
if path.is_file():
    ...

Prueba de archivos y carpetas con os.path.isfile() , os.path.isdir() y os.path.exists()

Suponiendo que la "ruta" es una ruta válida, esta tabla muestra lo que devuelve cada función para los archivos y carpetas:

También puede probar si un archivo es un cierto tipo de archivo usando os.path.splitext() para obtener la extensión (si aún no lo sabe)

>>> import os
>>> path = "path to a word document"
>>> os.path.isfile(path)
True
>>> os.path.splitext(path)[1] == ".docx" # test if the extension is .docx
True

Soy el autor de un paquete que ha existido durante unos 10 años y tiene una función que aborda esta pregunta directamente. Básicamente, si estás en un sistema que no es Windows, se usa Popenpara acceder find. Sin embargo, si está en Windows, se replica findcon un sistema de archivos eficiente.

El código en sí no usa un trybloque ... excepto para determinar el sistema operativo y así dirigirlo al estilo "Unix" findo al manual find. Las pruebas de tiempo mostraron que la trydeterminación del sistema operativo era más rápida, así que usé uno allí (pero en ningún otro lugar).

>>> import pox
>>> pox.find('*python*', type='file', root=pox.homedir(), recurse=False)
['/Users/mmckerns/.python']

Y el doc ...

>>> print pox.find.__doc__
find(patterns[,root,recurse,type]); Get path to a file or directory

    patterns: name or partial name string of items to search for
    root: path string of top-level directory to search
    recurse: if True, recurse down from root directory
    type: item filter; one of {None, file, dir, link, socket, block, char}
    verbose: if True, be a little verbose about the search

    On some OS, recursion can be specified by recursion depth (an integer).
    patterns can be specified with basic pattern matching. Additionally,
    multiple patterns can be specified by splitting patterns with a ';'
    For example:
        >>> find('pox*', root='..')
        ['/Users/foo/pox/pox', '/Users/foo/pox/scripts/pox_launcher.py']

        >>> find('*shutils*;*init*')
        ['/Users/foo/pox/pox/shutils.py', '/Users/foo/pox/pox/__init__.py']

>>>

La implementación, si te interesa mirar, está aquí: https://github.com/uqfoundation/pox/blob/89f90fb308f285ca7a62eabe2c38acb87e89dad9/pox/shutils.py#L190



Fecha: 2017-12-04

Todas las soluciones posibles han sido enumeradas en otras respuestas.

Una forma intuitiva y discutible de verificar si un archivo existe es la siguiente:

import os
os.path.isfile('~/file.md')    # Returns True if exists, else False
additionaly check a dir
os.path.isdir('~/folder') # Returns True if the folder exists, else False
check either a dir or a file
os.path.exists('~/file')

Hice una hoja de trucos exhaustiva para su referencia:

#os.path methods in exhaustive cheatsheet
{'definition': ['dirname',
               'basename',
               'abspath',
               'relpath',
               'commonpath',
               'normpath',
               'realpath'],
'operation': ['split', 'splitdrive', 'splitext',
               'join', 'normcase'],
'compare': ['samefile', 'sameopenfile', 'samestat'],
'condition': ['isdir',
              'isfile',
              'exists',
              'lexists'
              'islink',
              'isabs',
              'ismount',],
 'expand': ['expanduser',
            'expandvars'],
 'stat': ['getatime', 'getctime', 'getmtime',
          'getsize']}

Si el archivo es para abrir, puede utilizar una de las siguientes técnicas:

>>> with open('somefile', 'xt') as f: #Using the x-flag, Python3.3 and above
...     f.write('Hello\n')

>>> if not os.path.exists('somefile'): 
...     with open('somefile', 'wt') as f:
...         f.write("Hello\n")
... else:
...     print('File already exists!')

ACTUALIZAR

Solo para evitar confusiones y según las respuestas que recibí, la respuesta actual encuentra un archivo o un directorio con el nombre dado.


A diferencia de isfile() , exists() devolverá True para los directorios.
Entonces, dependiendo de si solo quieres archivos simples o directorios, isfile() o exists() . Aquí hay una salida simple de REPL.

>>> print os.path.isfile("/etc/password.txt")
True
>>> print os.path.isfile("/etc")
False
>>> print os.path.isfile("/does/not/exist")
False
>>> print os.path.exists("/etc/password.txt")
True
>>> print os.path.exists("/etc")
True
>>> print os.path.exists("/does/not/exist")
False

Si quieres enfrentarte a un archivo muy grande / grande y quieres leer más rápido (imagina que estás en una competencia de codificación Topcoder / Hackerrank), puedes leer un trozo de líneas considerablemente mayor en un búfer de memoria al mismo tiempo, en lugar de solo iterar línea por línea a nivel de archivo.

buffersize = 2**16
with open(path) as f: 
    while True:
        lines_buffer = f.readlines(buffersize)
        if not lines_buffer:
            break
        for line in lines_buffer:
            process(line)




python file file-exists