La biblioteca estándar de Python contiene la mayor parte de la funcionalidad que un desarrollador necesitaría para resolver un problema. En este tutorial, aprenderá diferentes formas de comprobar la existencia de un archivo o directorio utilizando únicamente módulos incorporados.
Comprobar si un archivo o script se encuentra en el lugar correcto es crucial para cualquier programa CLI. Su programa podría volverse inútil si un archivo específico no está en su lugar en el momento de la ejecución.
En el tutorial de hoy, aprenderá algunas formas rápidas de comprobar si un archivo o carpeta existe en Python.
Antes de comenzar
Antes de ejecutar cualquier comando a continuación, asegúrese de que tiene Python 3 instalado en su sistema. Abra su terminal y escriba el siguiente comando
python --version
# Python 3.9.5, mi resultado
Si tiene una versión 2.x, tendrá que utilizar el comando «python3». Consulte nuestra guía de instalación de Python si no tiene Python 3 instalado.
Utilizaremos algunos archivos de prueba a lo largo de este tutorial, así que asegúrese de crear los siguientes archivos:
touch archivodeprueba.txt
mkdir directoriodeprueba/
touch directorioprueba/otroarchivo.txt
Los comandos anteriores crean un archivo con el que jugar, un directorio de pruebas y otro archivo dentro del directorio de pruebas. Los archivos pueden estar vacíos ya que no necesitaremos leer su contenido,
Nota: Si utiliza Windows, configure esa sencilla estructura de archivos con un gestor gráfico de archivos.
Por último, utilizaremos Ipython como nuestro intérprete de comandos interactivo de Python, que proporciona una bonita interfaz con la que trabajar. Esto es sólo una comodidad, por lo tanto no es estrictamente necesario.
pip install ipython
Después de hacer esto, obtendrá acceso a una hermosa shell de Python con sólo teclear ipython.
Ahora que está todo listo vamos a sumergirnos en las formas de comprobar si una carpeta o archivo existe en Python.
Probar, Abrir y Excepto
Esta es la opción más directa. Si intenta abrir un archivo que no existe, Python lanzará un FileNotFoundError.
En <x><x><x><x><x><x><x><x><x><x><x><x>[1]</x></x></x></x></x></x></x></x></x></x></x></x>: open('im-not-here.txt')
---------------------------------------------------------------------------
FileNotFoundError: [Errno 2] No existe tal archivo o directorio: 'im-not-here.txt'
Podemos aprovecharnos de esto y manejar la excepción en caso de que el archivo que buscamos no exista.
En <x><x><x><x><x><x><x><x><x><x><x><x>[2</x></x></x></x></x></x></x></x></x></x></x></x>]: try:
...: file = open('im-no-aquí.txt')
...: print(archivo) # Manejador de archivos
...: archivo.cerrar()
...: except FileNotFoundError:
...: print('Lo sentimos, el archivo que buscamos no existe')
...: exit()
...:
Lo sentimos, el archivo que buscamos no existe
En el código anterior estamos imprimiendo un mensaje personalizado y deteniendo la ejecución del programa si el archivo no existe.
Observe cómo la función exit( ) sólo se ejecutará si se produce una excepción. Veamos qué ocurre cuando el archivo que buscamos existe realmente.
En <x><x><x><x><x><x><x><x><x><x><x><x><x>[2]</x></x></x></x></x></x></x></x></x></x></x></x></x>: try:
...: archivo = open('archivoprueba.txt')
...: print(archivo) # Manejador de archivos
...: archivo.cerrar()
...: except FileNotFoundError:
...: print('Lo sentimos, el archivo que buscamos no existe')
...: exit()
...:
<_io.TextIOWrapper name='testfile.txt' mode='r' encoding='UTF-8'>
Observe cómo cerramos el archivo justo después de abrirlo. Se considera una buena práctica según la
Llamar a
<span class="pre">file.write(</span>
) sin usar la palabra clave<span class="pre">with</span>
o llamar a<span class="pre">file.close()</span>
podría resultar en que los argumentos de<span class="pre">file.write</span>
() no se escriban completamente en el disco, incluso si el programa sale con éxito.
Incluso si no estamos escribiendo en el archivo, es extremadamente recomendable cerrar el archivo porque podría dar lugar a múltiples problemas de rendimiento.
Si no queremos cerrar el archivo por nosotros mismos, podemos utilizar el gestor de contexto with . Éste asigna y libera recursos de forma precisa, por lo que no necesitaremos cerrar el archivo.
En <x><x><x><x><x><x><x><x><x><x><x><x><x><x><x>[3]</x></x></x></x></x></x></x></x></x></x></x></x></x></x></x>: try:
...: with open('archivoprueba.txt') as archivo:
...: print(archivo)
...: # No es necesario cerrar el archivo
...: except FileNotFoundError:
...: print('Lo sentimos, el archivo que buscamos no existe')
...: exit()
...:
...:
<_io.TextIOWrapper name='archivoprueba.txt' mode='r' encoding='UTF-8'>
Este método es extremadamente útil cuando escribimos en archivos, pero resulta ineficaz si sólo queremos comprobar si un archivo existe. Veamos otras opciones para conseguirlo.
os.path.exists()
El módulo os proporciona múltiples funciones para interactuar con el sistema operativo. Para comprobar si un archivo o carpeta existe podemos utilizar la función path.exists() que acepta la ruta al archivo o directorio como argumento. Devuelve un booleano basado en la existencia de la ruta.
Nota: Una ruta es la ubicación única de un archivo o directorio en un sistema de archivos
En Python, el submódulo os.path contiene funciones diseñadas exclusivamente para operar con rutas de archivos. Todas estas funciones aceptan el argumento ruta como cadenas o bytes, y puede decidir trabajar con rutas absolutas, por ejemplo
/home/daniel/.bashrc
O con rutas relativas, dependiendo del directorio en el que esté ejecutando el script:
.bashrc
# Ejecutando el script en mi carpeta home
He aquí varios ejemplos que utilizan la función os.path.exists() , ejecutándose en el directorio en el que se encuentran mis archivos de prueba:
En <x><x><x><x><x><x><x><x><x><x><x><x>[1]</x></x></x></x></x></x></x></x></x></x></x></x>: import os
En <x><x><x><x><x><x><x><x><x><x><x><x>[</x></x></x></x></x></x></x></x></x></x></x></x>2]: os.path.exists('ficheroprueba.txt')
Fuera<x><x><x><x><x><x><x><x><x><x><x><x>[</x></x></x></x></x></x></x></x></x></x></x></x>2]: True
En <x><x><x><x><x><x><x><x><x><x><x><x><x><x><x>[3]</x></x></x></x></x></x></x></x></x></x></x></x></x></x></x>: os.path.exists('directorioprueba')
Salida<x><x><x><x><x><x><x><x><x><x><x>[</x></x></x></x></x></x></x></x></x></x></x>3]: True
En <x><x><x><x><x><x><x><x><x><x><x><x><x>[4]</x></x></x></x></x></x></x></x></x></x></x></x></x>: os.path.exists('hey-i-dont-exist')
Salida<x><x><x><x><x><x><x><x><x><x>[</x></x></x></x></x></x></x></x></x></x>4]: Falso
Como puede ver, devuelve True cuando la prueba se realiza con el archivo testfile.txt y la carpeta testdirectory, y False cuando el archivo no existe.
os.path.isfile()
Si sólo quisiera probar la existencia de un archivo (no de un directorio), llamaría a la función os.path. isfile().
En <x><x><x><x><x><x><x><x><x><x><x><x>[1]</x></x></x></x></x></x></x></x></x></x></x></x>: import os
En <x><x><x><x><x><x><x><x><x><x><x><x>[</x></x></x></x></x></x></x></x></x></x></x></x>2]: os.path.isfile('archivoprueba.txt')
Fuera<x><x><x><x><x><x><x><x><x><x><x><x>[</x></x></x></x></x></x></x></x></x></x></x></x>2]: True
En <x><x><x><x><x><x><x><x><x><x><x><x><x><x><x>[3]</x></x></x></x></x></x></x></x></x></x></x></x></x></x></x>: os.path.isfile('testdirectory/')
Salida<x><x><x><x><x><x><x><x><x><x><x>[</x></x></x></x></x></x></x></x></x></x></x>3]: Falso
En <x><x><x><x><x><x><x><x><x><x><x><x><x>[4]</x></x></x></x></x></x></x></x></x></x></x></x></x>: os.path.isfile('i-dont-even-exist')
Salida<x><x><x><x><x><x><x><x><x><x>[</x></x></x></x></x></x></x></x></x></x>4]: Falso
En <x><x><x><x><x><x><x><x>[5]</x></x></x></x></x></x></x></x>: os.path.isfile('testdirectory/otherfile.txt')
Fuera<x><x><x><x><x><x>[</x></x></x></x></x></x>5]: True
Nota: En UNIX todos los directorios terminan con una barra inclinada (/), mientras que en Windows utilizamos una barra invertida (\).
En el código anterior la función isfile( ) devuelve False en dos ocasiones, veamos por qué:
testdirectory/
es un directorio, por lo tanto no se considera como un archivo. Esto no es absolutamente cierto ya que en Linux todo es un descriptor de fichero, pero Python trata los directorios de forma diferente sólo por conveniencia (Si intenta abrir un directorio obtendrá un IsADirectoryError)i-dont-even-exist
está apuntando a un archivo que irónicamente no existe
os.path.isdir()
Si quiere comprobar que un directorio está en el lugar correcto, tendrá que utilizar la función os .path.isdir() , que sólo devuelve True si la ruta dada apunta a un directorio.
En <x><x><x><x><x><x><x><x><x><x><x><x>[1]</x></x></x></x></x></x></x></x></x></x></x></x>: import os
En <x><x><x><x><x><x><x><x><x><x><x><x>[</x></x></x></x></x></x></x></x></x></x></x></x>2]: os.path.isdir('archivoprueba.txt')
Fuera<x><x><x><x><x><x><x><x><x><x><x><x>[</x></x></x></x></x></x></x></x></x></x></x></x>2]: Falso
En <x><x><x><x><x><x><x><x><x><x><x><x><x><x><x>[3]</x></x></x></x></x></x></x></x></x></x></x></x></x></x></x>: os.path.isdir('directorioprueba')
Salida<x><x><x><x><x><x><x><x><x><x><x>[</x></x></x></x></x></x></x></x></x></x></x>3]: True
En <x><x><x><x><x><x><x><x><x><x><x><x><x>[4]</x></x></x></x></x></x></x></x></x></x></x></x></x>: os.path.isdir('otroarchivo.txt')
Salida<x><x><x><x><x><x><x><x><x><x>[</x></x></x></x></x></x></x></x></x></x>4]: Falso
Observe cómo los ejemplos anteriores devuelven False incluso cuando la ruta apunta a un archivo que existe.
Globo
El módulo glob proporciona funciones para trabajar con patrones tipo shell de Unix (de ahí que no funcione correctamente en Windows). Para comprobar si un archivo coincide con un patrón dentro del directorio actual, puede utilizar la función glob.glob().
En <x><x><x><x><x><x><x><x><x><x><x><x>[1]</x></x></x></x></x></x></x></x></x></x></x></x>: import glob
En <x><x><x><x><x><x><x><x><x><x><x><x>[</x></x></x></x></x></x></x></x></x></x></x></x>2]: glob.glob('archivoprueba.txt')
Fuera<x><x><x><x><x><x><x><x><x><x><x><x>[</x></x></x></x></x></x></x></x></x></x></x></x>2]: ['archivoprueba.txt']
En <x><x><x><x><x><x><x><x><x><x><x>[</x></x></x></x></x></x></x></x></x></x></x>3]: glob.glob('directorioprueba')
Salida<x><x><x><x><x><x><x><x><x><x><x>[</x></x></x></x></x></x></x></x></x></x></x>3]: ['directorioprueba']
En el código anterior, el patrón pasado a la función glob es una cadena normal que representa la ruta al archivo y directorio de prueba. Dado que ambas rutas existen, la función devuelve una lista con los nombres de ruta coincidentes en su interior.
Nota: Si el patrón no coincidiera obtendría una lista vacía.
Teniendo en cuenta que podemos pasar patrones a la función glob, ¿por qué no probar algunas de sus principales ventajas?
El código siguiente obtiene todas las rutas de archivos con extensión .txt y .py respectivamente:
En <x><x><x><x><x><x><x><x><x><x>[</x></x></x></x></x></x></x></x></x></x>4]: glob.glob('*.txt')
Fuera<x><x><x><x><x><x><x><x><x><x>[</x></x></x></x></x></x></x></x></x></x>4]: ['archivoprueba.txt']
En <x><x><x><x><x><x>[</x></x></x></x></x></x>5]: glob.glob('*.py')
Salida<x><x><x><x><x><x>[</x></x></x></x></x></x>5]:
['pathlib-existe.py',
'list-dir.py',
'glob-archivo.py',
'open-except.py',
'subproceso-prueba.py',
'isfile.py',
'existe.py',
isdir.py]
Uso de la clase Path
La clase Path es una de las mejores formas de trabajar con rutas ya que nos proporciona una interfaz limpia para trabajar con rutas de archivos como objetos.
La guinda del pastel es que las instancias de Path tienen todos los métodos necesarios para obtener información sobre una determinada ruta. Esto incluye funcionalidades similares a las opciones anteriores.
Nota: Necesitará Python 3.4 o superior para utilizar la biblioteca pathlib
Los métodos Path que utilizará:
Comprobar si existe una ruta
En <x><x><x><x><x><x><x><x><x><x><x><x>[1]</x></x></x></x></x></x></x></x></x></x></x></x>: from pathlib import Camino
En <x><x><x><x><x><x><x><x><x><x><x><x>[</x></x></x></x></x></x></x></x></x></x></x></x>2]: Camino('archivoprueba.txt').existe()
Fuera<x><x><x><x><x><x><x><x><x><x><x><x>[</x></x></x></x></x></x></x></x></x></x></x></x>2]: True
En <x><x><x><x><x><x><x><x><x><x><x>[</x></x></x></x></x></x></x></x></x></x></x>3]: Path('im-no-aquí.txt').existe()
Fuera[3<x><x><x><x><x><x><x><x><x><x><x>]</x></x></x></x></x></x></x></x></x></x></x>: Falso
En <x><x><x><x><x><x><x><x><x><x>[</x></x></x></x></x></x></x></x></x></x>4]: Ruta('directorioprueba').existe()
Fuera<x><x><x><x><x><x><x><x><x><x>[</x></x></x></x></x></x></x></x></x></x>4]: True
Funciona igual que os.path.exists().
Comprueba si la ruta apunta a un archivo
En <x><x><x><x><x><x><x><x>[5]</x></x></x></x></x></x></x></x>: Ruta('archivo_prueba.txt').es_archivo()
Fuera<x><x><x><x><x><x>[</x></x></x></x></x></x>5]: True
En <x><x>[</x></x>6]: Ruta('directorioprueba').es_archivo()
Fuera<x><x>[</x></x>6]: Falso
Equivalente a os.path.isfile().
Comprueba si la ruta apunta a un directorio
En <x><x><x>[7]</x></x></x>: Ruta('archivo_prueba.txt').is_dir()
Fuera<x><x>[</x></x>7]: Falso
En [8]: Path('directorio_prueba').is_dir()
Salida<x>[8]</x>: True
Corresponde a os.path.isdir().
subproceso
Si es un amante de los módulos de subproceso, necesitará conocer esta opción. Puede determinar si un archivo o carpeta existe utilizando el comando test.
Nota: El comando test sólo funciona en Unix.
Las siguientes banderas de prueba harán el trabajo:
- test -e: Comprueba si existe una ruta
- test -f: Comprueba si existe un archivo
- test-d: Comprueba si existe una carpeta
En caso de que desee profundizar en más banderas de prueba, puede leer el manual ejecutando
man test
Comprobación de una ruta con subproceso:
El código siguiente determina si existe una ruta comparando el código de retorno del subproceso con 0.
Recuerde que en Linux, si un proceso ha ido bien, devolverá cero, si no ha ido bien devolverá cualquier otro código.
En <x><x><x><x><x><x><x><x><x><x><x><x>[1]</x></x></x></x></x></x></x></x></x></x></x></x>: from subproceso import ejecutar
En <x><x><x><x><x><x><x><x><x><x><x><x>[</x></x></x></x></x></x></x></x></x></x></x></x>2]: run(['prueba', '-e', 'archivoprueba.txt']).returncode == 0
Fuera<x><x><x><x><x><x><x><x><x><x><x><x>[</x></x></x></x></x></x></x></x></x></x></x></x>2]: True
En <x><x><x><x><x><x><x><x><x><x><x>[</x></x></x></x></x></x></x></x></x></x></x>3]: run(['test', '-e', 'im-not-here.txt']).returncode == 0
Fuera<x><x><x><x><x><x><x><x><x><x><x>[</x></x></x></x></x></x></x></x></x></x></x>3]: Falso
En la primera sentencia, estamos importando el módulo de subproceso, y luego utilizando la función ejecutar y obteniendo su código de retorno.
Verificación de la existencia de un archivo con subproceso
En <x><x><x><x><x><x><x><x><x><x>[</x></x></x></x></x></x></x></x></x></x>4]: run(['prueba', '-f', 'archivoprueba.txt']).returncode == 0
Fuera<x><x><x><x><x><x><x><x><x><x>[</x></x></x></x></x></x></x></x></x></x>4]: True
En <x><x><x><x><x><x>[</x></x></x></x></x></x>5]: run(['prueba', '-f', 'directorioprueba']).returncode == 0
Fuera<x><x><x><x><x><x>[</x></x></x></x></x></x>5]: Falso
Comprobación de un directorio con subproceso:
En <x><x><x>[6]</x></x></x>: run(['prueba', '-d', 'archivoprueba.txt']).returncode == 0
Fuera<x><x>[</x></x>6]: Falso
En <x><x>[</x></x>7]: run(['prueba', '-d', 'directorioprueba']).returncode == 0
Fuera<x><x>[</x></x>7]: True
No es tan recomendable utilizar esta opción ya que consume más recursos y no obtenemos ninguna ventaja de ella.
En resumen
Python es uno de los lenguajes de programación más utilizados para automatizar procesos interactuando con el SO. Una cosa genial que se puede hacer con él es comprobar si un archivo o una carpeta existe.
Los más sencillos para hacerlo son:
- Abriendo y manejando de inmediato las excepciones de archivos
- Utilizando la función exists() de los módulos os.path o pathlib.
En este tutorial ha aprendido:
- Cómo abrir un archivo y manejar excepciones en caso de que no exista
- El significado de las rutas
- 3 funciones diferentes que proporciona el submódulo os. path para comprobar la existencia de un archivo o carpeta
- Unix utiliza barras hacia delante (/), mientras que Windows utiliza barras hacia atrás (\)
Siguiente lectura: ¿Qué es un subproceso en Python? [5 ejemplos de uso]