Cómo comprobar si una excepción es de un cierto tipo en Python

PythonPythonBeginner
Practicar Ahora

💡 Este tutorial está traducido por IA desde la versión en inglés. Para ver la versión original, puedes hacer clic aquí

Introducción

En este laboratorio, aprenderás cómo verificar si una excepción es de un cierto tipo en Python, una habilidad crucial para el manejo efectivo de errores. El laboratorio se centra en comprender la jerarquía de excepciones y utilizar este conocimiento para identificar tipos de excepciones específicos.

El laboratorio te guía a través de la exploración de la jerarquía de excepciones de Python, comenzando con la clase base BaseException y sus subclases como Exception. Crearás un script de Python, exception_hierarchy.py, para imprimir la jerarquía de excepciones, lo que te permitirá visualizar las relaciones entre diferentes clases de excepciones. Esta comprensión se aplicará luego en pasos posteriores para verificar tipos de excepciones utilizando isinstance() y comparaciones directas de clases.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL python(("Python")) -.-> python/ErrorandExceptionHandlingGroup(["Error and Exception Handling"]) python/ErrorandExceptionHandlingGroup -.-> python/catching_exceptions("Catching Exceptions") python/ErrorandExceptionHandlingGroup -.-> python/raising_exceptions("Raising Exceptions") python/ErrorandExceptionHandlingGroup -.-> python/custom_exceptions("Custom Exceptions") subgraph Lab Skills python/catching_exceptions -.-> lab-559609{{"Cómo comprobar si una excepción es de un cierto tipo en Python"}} python/raising_exceptions -.-> lab-559609{{"Cómo comprobar si una excepción es de un cierto tipo en Python"}} python/custom_exceptions -.-> lab-559609{{"Cómo comprobar si una excepción es de un cierto tipo en Python"}} end

Comprender la jerarquía de excepciones

En este paso, aprenderás sobre la jerarquía de excepciones en Python. Comprender esta jerarquía es crucial para el manejo efectivo de errores. Las excepciones en Python se organizan en una estructura similar a un árbol, con una clase base en la parte superior y clases de excepciones más específicas que heredan de ella.

La clase base para todas las excepciones es BaseException. Directamente heredando de BaseException están Exception, GeneratorExit, KeyboardInterrupt y SystemExit. La clase Exception es la superclase de la mayoría de las excepciones integradas que indican errores que podría encontrar tu programa.

Vamos a crear un script de Python para explorar esta jerarquía.

  1. Abre tu editor de VS Code.

  2. Crea un nuevo archivo llamado exception_hierarchy.py en el directorio ~/project.

    ~/project/exception_hierarchy.py
  3. Agrega el siguiente código al archivo exception_hierarchy.py:

    def print_exception_hierarchy(exception_class, indent=0):
        """Prints the exception hierarchy starting from a given exception class."""
        print('  ' * indent + str(exception_class))
        for subclass in exception_class.__subclasses__():
            print_exception_hierarchy(subclass, indent + 1)
    
    print("Exception Hierarchy:")
    print_exception_hierarchy(Exception)

    Este script define una función recursiva print_exception_hierarchy que imprime la jerarquía de excepciones a partir de la clase Exception.

  4. Ejecuta el script utilizando el siguiente comando en la terminal:

    python exception_hierarchy.py

    Esto imprimirá una estructura similar a un árbol de la jerarquía de excepciones en la terminal.

    Ejemplo de salida:

    Exception Hierarchy:
    <class 'Exception'>
      <class 'ArithmeticError'>
        <class 'FloatingPointError'>
        <class 'OverflowError'>
        <class 'ZeroDivisionError'>
          <class 'decimal.DivisionByZero'>
      <class 'AssertionError'>
      <class 'AttributeError'>
      <class 'BufferError'>
      <class 'EOFError'>
      <class 'ImportError'>
        <class 'ModuleNotFoundError'>
        <class 'ZipImportError'>
      <class 'LookupError'>
        <class 'IndexError'>
        <class 'KeyError'>
          <class 'tracemalloc.DomainKey'>
      <class 'MemoryError'>
      <class 'NameError'>
        <class 'UnboundLocalError'>
      <class 'OSError'>
        <class 'BlockingIOError'>
        <class 'ChildProcessError'>
        <class 'ConnectionError'>
          <class 'BrokenPipeError'>
          <class 'ConnectionAbortedError'>
          <class 'ConnectionRefusedError'>
          <class 'ConnectionResetError'>
        <class 'FileExistsError'>
        <class 'FileNotFoundError'>
        <class 'InterruptedError'>
          <class 'InterruptedSystemCall'>
        <class 'IsADirectoryError'>
        <class 'NotADirectoryError'>
        <class 'PermissionError'>
        <class 'ProcessLookupError'>
        <class 'TimeoutError'>
        <class 'UnsupportedOperation'>
        <class 'itertools.Incomplete'>
        <class 'signal.ItimerError'>
      <class 'ReferenceError'>
      <class 'RuntimeError'>
        <class 'NotImplementedError'>
          <class 'asyncio.exceptions.IncompleteReadError'>
          <class 'zlib.error'>
        <class '_frozen_importlib._DeadlockError'>
        <class 'RecursionError'>
      <class 'StopAsyncIteration'>
      <class 'StopIteration'>
      <class 'SyntaxError'>
        <class 'IndentationError'>
          <class 'TabError'>
      <class 'SystemError'>
      <class 'TypeError'>
      <class 'ValueError'>
        <class 'UnicodeError'>
          <class 'UnicodeDecodeError'>
          <class 'UnicodeEncodeError'>
          <class 'UnicodeTranslateError'>
      <class 'Warning'>
        <class 'BytesWarning'>
        <class 'DeprecationWarning'>
        <class 'EncodingWarning'>
        <class 'FutureWarning'>
        <class 'ImportWarning'>
        <class 'PendingDeprecationWarning'>
        <class 'ResourceWarning'>
        <class 'RuntimeWarning'>
        <class 'SyntaxWarning'>
        <class 'UnicodeWarning'>
        <class 'UserWarning'>

    Esta salida muestra la jerarquía de excepciones, con Exception como clase base y varias subclases que representan tipos específicos de errores. Comprender esta jerarquía te ayuda a capturar excepciones en el nivel de granularidad adecuado. Por ejemplo, puedes capturar una excepción específica como ZeroDivisionError o una excepción más general como ArithmeticError (que es el padre de ZeroDivisionError).

Usar isinstance() en excepciones

En este paso, aprenderás cómo usar la función isinstance() para verificar si una excepción es una instancia de una clase particular o de una tupla de clases. Esto es útil para manejar diferentes tipos de excepciones de manera flexible.

La función isinstance() toma dos argumentos: un objeto y un classinfo. Devuelve True si el objeto es una instancia de classinfo, o de una subclase de ella. Devuelve False en caso contrario.

Vamos a crear un script de Python para demostrar el uso de isinstance() con excepciones.

  1. Abre tu editor de VS Code.

  2. Crea un nuevo archivo llamado isinstance_exception.py en el directorio ~/project.

    ~/project/isinstance_exception.py
  3. Agrega el siguiente código al archivo isinstance_exception.py:

    try:
        result = 10 / 0
    except Exception as e:
        if isinstance(e, ZeroDivisionError):
            print("Caught a ZeroDivisionError!")
        elif isinstance(e, ArithmeticError):
            print("Caught an ArithmeticError!")
        else:
            print("Caught some other exception!")
    
    print("Program continues...")

    En este script, estamos intentando dividir 10 entre 0, lo que generará una excepción ZeroDivisionError. Luego capturamos la excepción y usamos isinstance() para verificar si es una instancia de ZeroDivisionError o ArithmeticError.

  4. Ejecuta el script utilizando el siguiente comando en la terminal:

    python isinstance_exception.py

    Esto imprimirá "Caught a ZeroDivisionError!" en la terminal.

    Ejemplo de salida:

    Caught a ZeroDivisionError!
    Program continues...

    La salida muestra que la función isinstance() identificó correctamente la excepción como una instancia de ZeroDivisionError. Debido a que ZeroDivisionError es una subclase de ArithmeticError, se cumple la primera condición if y se imprime el mensaje correspondiente.

    Ahora, modifiquemos el script para capturar una excepción más general.

  5. Modifica el archivo isinstance_exception.py para que sea el siguiente:

    try:
        result = int("abc")
    except Exception as e:
        if isinstance(e, ZeroDivisionError):
            print("Caught a ZeroDivisionError!")
        elif isinstance(e, ValueError):
            print("Caught a ValueError!")
        elif isinstance(e, ArithmeticError):
            print("Caught an ArithmeticError!")
        else:
            print("Caught some other exception!")
    
    print("Program continues...")

    En este script modificado, estamos intentando convertir la cadena "abc" en un entero, lo que generará una excepción ValueError.

  6. Ejecuta el script nuevamente utilizando el mismo comando:

    python isinstance_exception.py

    Esto imprimirá "Caught a ValueError!" en la terminal.

    Ejemplo de salida:

    Caught a ValueError!
    Program continues...

    Esta salida muestra que isinstance() se puede utilizar para diferenciar entre diferentes tipos de excepciones y manejarlas en consecuencia.

Verificar con clases de excepciones

En este paso, aprenderás cómo verificar clases de excepciones específicas directamente en tus bloques except. Esto es una forma más directa y, a menudo, más clara de manejar excepciones en comparación con el uso de isinstance().

Cuando usas except ExceptionType as e:, estás indicando a Python que capture solo las excepciones que son del tipo ExceptionType o de una subclase de ella.

Vamos a crear un script de Python para demostrar esto.

  1. Abre tu editor de VS Code.

  2. Crea un nuevo archivo llamado exception_classes.py en el directorio ~/project.

    ~/project/exception_classes.py
  3. Agrega el siguiente código al archivo exception_classes.py:

    try:
        result = 10 / 0
    except ZeroDivisionError as e:
        print("Caught a ZeroDivisionError:", e)
    except ArithmeticError as e:
        print("Caught an ArithmeticError:", e)
    except Exception as e:
        print("Caught some other exception:", e)
    
    print("Program continues...")

    En este script, estamos intentando dividir 10 entre 0, lo que generará una excepción ZeroDivisionError. Tenemos tres bloques except: uno para ZeroDivisionError, uno para ArithmeticError y uno para Exception.

  4. Ejecuta el script utilizando el siguiente comando en la terminal:

    python exception_classes.py

    Esto imprimirá "Caught a ZeroDivisionError: division by zero" en la terminal.

    Ejemplo de salida:

    Caught a ZeroDivisionError: division by zero
    Program continues...

    La salida muestra que la excepción ZeroDivisionError fue capturada por el primer bloque except.

    Ahora, modifiquemos el script para generar una excepción diferente.

  5. Modifica el archivo exception_classes.py para que sea el siguiente:

    try:
        result = int("abc")
    except ZeroDivisionError as e:
        print("Caught a ZeroDivisionError:", e)
    except ValueError as e:
        print("Caught a ValueError:", e)
    except ArithmeticError as e:
        print("Caught an ArithmeticError:", e)
    except Exception as e:
        print("Caught some other exception:", e)
    
    print("Program continues...")

    En este script modificado, estamos intentando convertir la cadena "abc" en un entero, lo que generará una excepción ValueError.

  6. Ejecuta el script nuevamente utilizando el mismo comando:

    python exception_classes.py

    Esto imprimirá "Caught a ValueError: invalid literal for int() with base 10: 'abc'" en la terminal.

    Ejemplo de salida:

    Caught a ValueError: invalid literal for int() with base 10: 'abc'
    Program continues...

    Esta salida muestra que la excepción ValueError fue capturada por el segundo bloque except.

    Al especificar la clase de excepción directamente en el bloque except, puedes manejar diferentes tipos de excepciones de manera clara y organizada. Este enfoque generalmente se prefiere sobre el uso de isinstance() para el manejo simple de excepciones.

Resumen

En este laboratorio, exploraste la jerarquía de excepciones en Python, que es crucial para un manejo efectivo de errores. Aprendiste que las excepciones están organizadas en una estructura en forma de árbol con BaseException como clase base y Exception como superclase para la mayoría de las excepciones incorporadas.

Creadiste un script de Python, exception_hierarchy.py, para imprimir la jerarquía de excepciones a partir de la clase Exception. Al ejecutar el script, observaste la estructura en forma de árbol de las excepciones y sus relaciones, lo que te permitió comprender mejor cómo están organizadas las excepciones en Python.