[Python] ¿Cómo verificar si existe un archivo?



Answers

Usted tiene la función os.path.exists :

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

Esto devuelve True para ambos archivos y directorios pero en su lugar puede usar os.path.isfile para probar si se trata de un archivo específicamente. Sigue los enlaces simbólicos.

Question

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




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 continuar ejecutándose desde allí o puede codificar para detenerlo si lo desea.




import os
os.path.exists(path) # returns whether the path (dir or file) exists or not
os.path.isfile(path) # returns whether the file exists or not



import os
#Your path here e.g. "C:\Program Files\text.txt"
#For access purposes: "C:\\Program Files\\text.txt"
if os.path.exists("C:\..."):   
    print "File found!"
else:
    print "File not found!"

Importar el sistema operativo hace que sea más fácil navegar y realizar acciones estándar con su sistema operativo.

Para referencia también vea share

Si necesita operaciones de alto nivel, use shutil .




import os.path

if os.path.isfile(filepath):



I'm the author of a package that's been around for about 10 years, and it has a function that addresses this question directly. Basically, if you are on a non-Windows system, it uses Popen to access find . However, if you are on Windows, it replicates find with an efficient filesystem walker.

The code itself does not use a try block… except in determining the operating system and thus steering you to the "Unix"-style find or the hand-buillt find . Timing tests showed that the try was faster in determining the OS, so I did use one there (but nowhere else).

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

And the 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']

>>>

The implementation, if you care to look, is here: https://github.com/uqfoundation/pox/blob/89f90fb308f285ca7a62eabe2c38acb87e89dad9/pox/shutils.py#L190




import os
path = /path/to/dir

root,dirs,files = os.walk(path).next()
if myfile in files:
   print "yes it exists"

This is helpful when checking for several files. Or you want to do a set intersection/ subtraction with an existing list.




2017/12/22 :

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

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

Declaración del problema :

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

Posibles soluciones :

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

    os.path.exists(path)
    

    Devuelve True si la ruta hace referencia 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 permiso para ejecutar os.stat() en el archivo solicitado, incluso si la ruta existe físicamente.

    Todo bien, pero si sigues 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 alrededor de os.stat() os.stat() . Entonces, tu código es try/except free, pero más abajo en el framestack hay (al menos) uno de esos bloques. Esto también se aplica a otros funcs ( incluido os.path.isfile ).

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

    • Es un modo más elegante (y más python ic) de manejar caminos, pero
    • Debajo del 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 gestores 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 del 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
        
    • Use [Python]: contextlib. suprimir ( * excepciones ) - que fue diseñado específicamente para suprimir selectivamente excepciones


    Pero, parecen ser envoltorios sobre los bloques try/except/else/finally , como [Python]: el enunciado con dice:

    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 buscar los resultados para los elementos coincidentes)


    Dado que estos iteran sobre las carpetas, (en la mayoría de los casos) son ineficaces para nuestro problema (hay excepciones, como el comodín no comodín, como señaló @ShadowRanger), así que no voy a insistir en ellos. Sin mencionar que, en algunos casos, es posible que se requiera el procesamiento del nombre de archivo.

  4. [Python]: os. access ( path, mode, *, dir_fd = None, 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 usuario pueden restringir el archivo "visibilidad" como dice el documento:

      ... prueba si el usuario que realiza la invocación tiene el acceso especificado a la ruta . 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 a las API nativas (de nuevo, a través de " $ {PYTHON_SRC_DIR} / Modules / postixmodule.c "), pero también abre una puerta para un posible usuario errores , y no es tan Python ic como otras variantes. Entonces, como @AaronHall correctamente señaló, no lo use a menos que sepa lo que está haciendo:

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

    ( Win específico): como msvcr * ( vcruntime * ) exporta una [MSDN]: _access, _waccess function family también, 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 entre sí)
    • Aunque 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 cambio, la ruta de hardcoding libc ( "/lib/x86_64-linux-gnu/libc.so.6" ) que puede (y muy probablemente variará) entre sistemas, None (o la cadena vacía) se puede pasar al constructor CDLL ( ctypes.CDLL(None).access(b"/tmp", os.F_OK) ). De acuerdo con [hombre]: DLOPEN (3) :

      Si el nombre de archivo es NULL, el identificador devuelto es para el programa principal. Cuando se le asigna a dlsym (), este manejador 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 se cargarán sus símbolos (incluido el access )
      • Esto debe manejarse con cuidado, ya que funciones como main , Py_Main y (todas) otras están disponibles; llamarlos podría tener efectos desastrosos (en el programa actual)
      • Esto tampoco se aplica a Win (pero eso no es un problema, ya que msvcrt.dll se encuentra en "% SystemRoot% \ System32", que está en % PATH% de forma predeterminada). Quería llevar las cosas más lejos y reproducir este comportamiento en Win (y enviar un parche), pero resulta que [MSDN]: la función GetProcAddress solo "ve" los símbolos exportados , a menos que alguien declare las funciones en el ejecutable principal como __declspec(dllexport) (¿por qué en la Tierra la persona __declspec(dllexport) haría eso?), el programa principal es cargable pero prácticamente inutilizable
  5. Instale un tercer módulo Party con capacidades de sistema de archivos

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

    Pero, como esto es más como una solución alternativa, me estoy deteniendo aquí.

  6. Otra (lamentable) solución alternativa ( gainarie ) es (como me gusta llamarlo) el enfoque sysadmin : usar Python como envoltorio para ejecutar comandos de shell

    • Ganar :

      (py35x64_test) e:\Work\Dev\\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\\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 ):

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

En pocas palabras :

  • Utilice los bloques try / except / else / finally , ya que pueden evitar que se encuentre con una serie de problemas desagradables. Un contraejemplo que puedo pensar es el rendimiento: tales bloques son costosos, así que trate de no colocarlos en un 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 (s) final (es) :

  • Trataré de mantenerlo actualizado, cualquier sugerencia es bienvenida, incorporaré todo lo útil que surja en la respuesta



If the file is for opening you could use one of the following techniques:

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



No parece que haya una diferencia funcional significativa entre try / except y isfile() , por lo que debe 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, haga

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, ese es un asunto diferente.




Python 3.4+ tiene un módulo de ruta orientada a objetos: pathlib . Usando este nuevo módulo, puede 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

Puedes (y siempre deberías) 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 interesantes: comodín conveniente, comprobación del propietario del archivo, unión de rutas más fácil, etc. Vale la pena echarle un vistazo. Si está en una versión anterior de Python (versión 2.6 o posterior), aún puede instalar pathlib con pip:

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

Luego impórtalo de la siguiente manera:

# Older Python versions
import pathlib2 as pathlib



Here's a 1 line Python command for the Linux command line environment. I find this VERY HANDY since I'm not such a hot Bash guy.

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

I hope this is helpful.




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

Raising exceptions is considered to be an acceptable, and Pythonic, approach for flow control in your program. Consider handling missing files with IOErrors. In this situation, an IOError exception will be raised if the file exists but the user does not have read permissions.

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




You can use the "OS" library of Python:

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



Additionally, os.access() :

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

Being R_OK , W_OK , and X_OK the flags to test for permissions ( doc ).




Links