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 nuestro guía de instalación de Python si no tiene Python 3 instalado
Utilizaremos algunos archivos de prueba junto con este tutorial, así que asegúrese de crear los siguientes archivos
touch testfile.txt
mkdir
testdirectory/
touch testdirectory/otherfile.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 ya 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>[1]</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><x>[2]</x></x></x></x></x></x></x></x></x></x></x></x></x>: try:
...: file = open('im-not-here.txt')
...: print(file) # File handler
...: file.close()
...: 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 funciona salir( ) 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:
...: file = open('testfile.txt')
...: print(file) # File handler
...: file.close()
...: 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 documentación de Python
Llamar a
<span class="pre">file.write(</span>
) sin usar la palabra clave<span class="pre">with</span>
o llame a<span class="pre">file.close()</span>
podría resultar en que los argumentos de<span class="pre">file.write</span>
() no se escriben 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 con . Éste asigna y libera recursos con precisión, por lo que no necesitaremos cerrar el archivo
En <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>: try:
...: with open('testfile.txt') as file:
...: print(file)
...: # No es necesario cerrar el archivo
...: except FileNotFoundError:
...: print('Lo sentimos, el archivo que buscamos no existe')
...: exit()
...:
...:
<_io.TextIOWrapper name='testfile.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 camino.existe() 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 ruta.os 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
Inicio
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>[1</x></x></x></x></x></x>]: import os
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>: os.path.exists('archivodepruebas.txt')
Out<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>: True
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>3]: os.path.exists('directoriodepruebas')
Out<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>: True
En <x><x><x><x><x><x><x><x><x><x><x>[</x></x></x></x></x></x></x></x></x></x></x>4]: os.path.exists('hey-i-dont-exist')
Out<x><x><x><x><x><x><x><x><x><x><x>[4]</x></x></x></x></x></x></x></x></x></x></x>: Falso
Como puede ver, devuelve Verdadero cuando la prueba se realiza con el archivo testfile.txt y la carpeta testdirectory, y Falso 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>[1</x></x></x></x></x></x>]: import os
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>: os.path.isfile('archivoprueba.txt')
Out<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>: True
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>3]: os.path.isfile('testdirectory/')
Out<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>: Falso
En <x><x><x><x><x><x><x><x><x><x><x>[</x></x></x></x></x></x></x></x></x></x></x>4]: os.path.isfile('i-dont-even-exist')
Out<x><x><x><x><x><x><x><x><x><x><x>[4]</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>5]: os.path.isfile('testdirectory/otherfile.txt')
Out<x><x><x><x><x><x><x>[5]</x></x></x></x></x></x></x>: Verdadero
Nota: En UNIX todos los directorios terminan con una barra oblicua (/), mientras que en Windows utilizamos una barra invertida (\)
En el código anterior la función isfile( ) devolver Falso 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 desea comprobar que un directorio se encuentra en el lugar correcto, deberá utilizar la función os. ruta.isdir (), que sólo devuelve Verdadero si la ruta dada apunta a un directorio
En <x><x><x><x><x><x>[1</x></x></x></x></x></x>]: import os
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>: os.path.isdir('archivoprueba.txt')
Out<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>: Falso
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>3]: os.path.isdir('testdirectory')
Out<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>: True
In <x><x><x><x><x><x><x><x><x><x><x>[</x></x></x></x></x></x></x></x></x></x></x>4]: os.path.isdir('otroarchivo.txt')
Out<x><x><x><x><x><x><x><x><x><x><x>[4]</x></x></x></x></x></x></x></x></x></x></x>: Falso
Observe cómo se devuelven los ejemplos anteriores Falso 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()
In <x><x><x><x><x><x>[1]</x></x></x></x></x></x>: import glob
In <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>: glob.glob('archivoprueba.txt')
Out<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>: ['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></x></x>3]: glob.glob('directorioprueba')
Salida<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>:
['directorioprueba
'
]
En el código anterior, el patrón pasado a la función glob era una cadena normal que representaba 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
In <x><x><x><x><x><x><x><x><x><x><x>[4]</x></x></x></x></x></x></x></x></x></x></x>: glob.glob('*.txt')
Out<x><x><x><x><x><x><x><x><x><x><x>[4]</x></x></x></x></x></x></x></x></x></x></x>: ['archivo-prueba.txt']
En
<x><x><x><x><x><x><x>[</x></x></x></x></x></x></x>
5]:
glob.glob('*.py')
Out<x><x><x><x><x><x><x>[</x></x></x></x></x></x></x>
5]
:
[
'pathlib-exists.py',
'list-dir.py',
'glob-file.py',
'open-except.py',
'subprocess-test.py',
'isfile.py',
'exists.py',
'isdir.py']
Uso de la clase Path
La clase Ruta 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 [1 <x><x><x><x><x><x>]</x></x></x></x></x></x>: from pathlib import Path
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></x></x>2]: Path('archivo_prueba.txt').existe()
Out<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>: True
In <x><x><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-not-here.txt').exists()
Out<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>: Falso
En <x><x><x><x><x><x><x><x><x><x><x>[</x></x></x></x></x></x></x></x></x></x></x>4]: Path('testdirectory').exists()
Out<x><x><x><x><x><x><x><x><x><x><x>[4]</x></x></x></x></x></x></x></x></x></x></x>: Verdadero
Funciona igual que os.path.exists()
Comprueba si la ruta apunta a un archivo
En <x><x><x><x><x><x><x>[</x></x></x></x></x></x></x>5]: Path('testfile.txt').is_file()
Out<x><x><x><x><x><x><x>[5]</x></x></x></x></x></x></x>: True
En <x><x><x>[</x></x></x>6]: Path('testdirectory').is_file()
Out<x><x><x>[6]</x></x></x>: Falso
Equivalente a os.path.isfile()
Comprueba si la ruta apunta a un directorio
En <x><x><x>[</x></x></x>7]: Path('archivo_prueba.txt').is_dir()
Out<x><x><x>[7]</x></x></x>: Falso
En <x>[</x>8]: Path('testdirectory').is_dir()
Out<x>[8]</x>: Verdadero
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 prueba
Nota: El comando prueba sólo funciona en Unix
Las siguientes banderas de prueba harán el trabajo
- prueba -e: Comprueba si existe una ruta
- prueba -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 [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>[2]</x></x></x></x></x></x></x></x></x></x></x></x></x>: ejecutar(['prueba', '-e', 'archivoprueba.txt']).returncode == 0
Out<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>: True
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>3]: run(['prueba', '-e', 'im-no-está-aquí.txt']).returncode == 0
Out<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>: Falso
En la primera sentencia, estamos importando el módulo de subproceso, y luego utilizando la función ejecutar y obtener 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></x></x>4]: run(['prueba', '-f', 'archivoprueba.txt']).returncode == 0
Out<x><x><x><x><x><x><x><x><x><x><x>[4]</x></x></x></x></x></x></x></x></x></x></x>: True
En <x><x><x><x><x><x><x>[</x></x></x></x></x></x></x>5]: run(['test', '-f', 'testdirectory']).returncode == 0
Out<x><x><x><x><x><x><x>[5]</x></x></x></x></x></x></x>: Falso
Comprobación de un directorio con subproceso:
En <x><x><x>[</x></x></x>6]: run(['test', '-d', 'testarchivo.txt']).returncode == 0
Out[6<x><x><x>]</x></x></x>: Falso
En <x><x><x>[7]</x></x></x>: run(['test', '-d', 'testdirectory']).returncode == 0
Out<x><x><x>[7]</x></x></x>: True
No es tan recomendable utilizar esta opción ya que consume más recursos y no obtenemos ninguna ventaja de ella
Resumiendo
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
Las más sencillas para hacerlo son
- Abriendo y manejando de inmediato las excepciones de archivos
- Utilizando la función existe() de los módulos ruta.os 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. ruta 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]