En Python, todas las excepciones derivan de la clase BaseException. Esto significa que cada excepción en Python es una instancia de BaseException o de una de sus subclases.
La clase BaseException es la clase de nivel superior en la jerarquía de excepciones. Proporciona algunos métodos comunes que todas las excepciones pueden usar, como __str__ y __repr__. Sin embargo, no debes usar BaseException directamente en tu código, ya que es demasiado general y puede capturar cualquier tipo de excepción. En su lugar, debes utilizar clases de excepción más específicas que sean subclases de BaseException. Python proporciona varias clases de excepciones integradas que puedes usar, y también puedes crear tus propias clases de excepciones personalizadas:
The hierarchy of built-in exception classes in Python (from the official Python docs).
Esto significa que FileNotFoundError es una subclase de OSError, que es una subclase de la clase Exception, que a su vez hereda de BaseException.
Respetando la jerarquía de excepciones
Al usar múltiples sentencias except, es importante respetar la jerarquía de excepciones en Python. Esto significa que si capturas una clase de excepción base, como Exception, debes capturar excepciones más específicas antes que ella. Si escribes una sentencia except de una clase más específica después de la clase base, ese bloque no se ejecutará:
try:
# algún código que puede generar una excepción
except ValueError:
# manejar el ValueError
except Exception:
# manejar cualquier otra excepción
En este ejemplo, la excepción ValueError se captura primero. Si el código genera cualquier otra excepción que deriva de Exception, el código en el segundo bloque except se ejecutará. Sin embargo, no se recomienda capturar directamente Exception, ya que es demasiado general y puede capturar cualquier tipo de excepción. Es mejor capturar excepciones más específicas siempre que sea posible:
Si el código en el bloque try genera un TypeError o un ValueError, el bloque except correspondiente se ejecutará. Si el código genera cualquier otra excepción que derive de Exception, el código en el tercer bloque except se ejecutará.
Si colocamos la excepción base como el primer bloque except, evitará que el resto sean ejecutados:
try:
# algún código que puede generar una excepción
except Exception as e: # Esto capturará todos los errores
print(f'Ocurrió un error: {e}')
except ValueError: # Esto nunca se ejecutará
print('Ocurrió un ValueError')
except TypeError: # Esto nunca se ejecutará
print('Ocurrió un TypeError')
En este ejemplo, el bloque try puede generar cualquier tipo de excepción. Sin embargo, la primera sentencia except captura la clase base Exception, por lo que capturará cualquier excepción que se genere. Se imprimirá el mensaje de error y el resto de las sentencias except no se ejecutarán.
Desafío: Analizar el Archivo
Trabajas como ingeniero de software en una startup que maneja grandes volúmenes de datos. Recientemente, el equipo decidió usar archivos JSON para almacenar y procesar los datos. Estos datos son vitales para el funcionamiento de tu startup, y es tu tarea escribir un programa en Python que lea y analice estos archivos JSON.
Sin embargo, debido a la gran cantidad de datos y a que varias personas trabajan en ellos, a menudo ocurren algunos errores:
A veces el archivo de datos no existe.
A veces el archivo de datos está vacío.
A veces el archivo de datos contiene datos que no son JSON válido.
Necesitas asegurarte de que tu programa en Python pueda manejar estas excepciones sin fallar y proporcionar mensajes de error significativos para que el equipo de datos pueda identificar y solucionar rápidamente el problema.
Tu programa debe tomar como entrada una cadena que representa el nombre del archivo y manejar los siguientes casos:
Si el archivo no existe, debe lanzar un FileNotFoundError y mostrar un mensaje de error apropiado.
Si el archivo está vacío, debe lanzar un ValueError y mostrar un mensaje de error apropiado.
Si el contenido del archivo no es JSON válido, debe lanzar un json.JSONDecodeError (que es una subclase de ValueError) y mostrar un mensaje de error apropiado. Al lanzar esta excepción, debes proporcionar los atributos doc y pos como parámetros.
💡
except json.JSONDecodeError as e:
Cada una de estas excepciones debe ser manejada de forma independiente entre sí, y tu programa debe proporcionar un mensaje de error específico para cada caso.
Entrada
Salida
nonexistent_file.json
FileNotFoundError: File 'nonexistent_file.json' does not exist.
empty_file.json
ValueError: File 'empty_file.json' is empty.
invalid_json.json
JSONDecodeError: Content of file 'invalid_json.json' is not valid JSON.: line 1 column 1 (char 0)
success.json
File 'success.json' has been successfully parsed as valid JSON.