Python Built-in Exceptions: Error Handling for AI Code

Master Python's built-in exceptions to build robust AI and machine learning applications. Learn to handle runtime errors for resilient code.

7.5 Built-in Exceptions in Python

Built-in exceptions in Python are predefined classes that help manage runtime errors and unexpected events within a program. These exceptions are an integral part of Python's standard library and all inherit from the BaseException class, forming a robust hierarchy for error management. Understanding and effectively handling these exceptions is crucial for developing robust, maintainable, and error-resistant Python code.

What is an Exception in Python?

An exception is an event that occurs during program execution that disrupts the normal flow of instructions. Python employs exception handling mechanisms to manage these errors gracefully, preventing program crashes and allowing for controlled responses to unexpected situations.

Key Definitions

  • Exception: An abnormal event that interrupts the normal flow of code execution.
  • Built-in Exception: Predefined error classes readily available in Python to represent common error conditions.
  • Hierarchy: A structured, tree-like organization of exceptions, starting from the base class BaseException, from which all other built-in exceptions inherit.

Common Built-in Exceptions in Python

Python provides a wide array of built-in exceptions to categorize and handle various error scenarios. Here are some of the most common ones:

No.Exception NameDescription
1ExceptionThe base class for most built-in exceptions.
2StopIterationRaised when an iterator has no more items to yield.
3SystemExitRaised by sys.exit() to terminate the program.
4ArithmeticErrorBase class for all numeric calculation errors.
5OverflowErrorRaised when a number exceeds its maximum representable limit.
6FloatingPointErrorRaised for floating-point calculation errors.
7ZeroDivisionErrorRaised when attempting to divide a number by zero.
8AssertionErrorRaised when an assert statement fails.
9AttributeErrorRaised when an attribute reference or assignment fails.
10EOFErrorRaised when the input() function hits the end-of-file condition.
11ImportErrorRaised when an import statement fails to find a module.
12ModuleNotFoundErrorRaised when a specified module cannot be found (subclass of ImportError).
13KeyboardInterruptRaised when the user interrupts execution (e.g., by pressing Ctrl+C).
14IndexErrorRaised when accessing an index out of the valid range in a sequence (like lists or tuples).
15KeyErrorRaised when a dictionary key is not found.
16NameErrorRaised when a local or global name is not found.
17UnboundLocalErrorRaised when referencing a local variable before it has been assigned a value.
18OSErrorRaised for system-related errors (e.g., file access issues).
19IOErrorRaised for I/O operation errors (merged into OSError in Python 3).
20SyntaxErrorRaised when the code has invalid Python syntax.
21IndentationErrorRaised when there is an incorrect indentation in the code.
22TypeErrorRaised when an operation or function is applied to an object of an inappropriate type.
23ValueErrorRaised when a function receives an argument of the correct type but an inappropriate value.
24RuntimeErrorRaised when an error is detected that doesn't fall into any other category.
25NotImplementedErrorRaised by abstract methods to indicate that they must be implemented by subclasses.

Exception Class Hierarchy (Simplified)

Understanding the hierarchy helps in catching broader categories of exceptions.

BaseException
├── SystemExit
├── KeyboardInterrupt
└── Exception
    ├── ArithmeticError
    │    ├── FloatingPointError
    │    ├── OverflowError
    │    └── ZeroDivisionError
    ├── AssertionError
    ├── AttributeError
    ├── EOFError
    ├── ImportError
    │    └── ModuleNotFoundError
    ├── LookupError
    │    ├── IndexError
    │    └── KeyError
    ├── MemoryError
    ├── NameError
    │    └── UnboundLocalError
    ├── OSError
    │    └── FileNotFoundError
    ├── TypeError
    └── ValueError

Python Exception Examples

Let's illustrate some common exceptions with practical examples:

IndexError

numbers = [10, 20, 30]
print(numbers[3])

Output:

IndexError: list index out of range

ModuleNotFoundError

import unknown_module

Output:

ModuleNotFoundError: No module named 'unknown_module'

KeyError

data = {'a': 1, 'b': 2}
print(data['c'])

Output:

KeyError: 'c'

ImportError

from math import unknown_function

Output:

ImportError: cannot import name 'unknown_function'

StopIteration

it = iter([1, 2])
next(it)
next(it)
next(it) # This will raise StopIteration

Output:

StopIteration

TypeError

print('Age: ' + 25)

Output:

TypeError: can only concatenate str (not "int") to str

ValueError

num = int('hello')

Output:

ValueError: invalid literal for int() with base 10: 'hello'

NameError

print(score)

Output:

NameError: name 'score' is not defined

ZeroDivisionError

result = 5 / 0

Output:

ZeroDivisionError: division by zero

KeyboardInterrupt

name = input("Enter your name: ")
# User presses Ctrl+C during input

Output (when Ctrl+C is pressed):

KeyboardInterrupt

Exception Handling in Python

Python provides try, except, else, and finally blocks for robust exception handling.

Using try-except Block

The try block contains code that might raise an exception, and the except block handles it.

try:
    x = 10 / 0
except ZeroDivisionError as e:
    print(f"Error: {e}")

Output:

Error: division by zero

Handling Multiple Exceptions

You can catch multiple exception types in a single except block by providing them as a tuple, or by using separate except blocks for each specific exception.

try:
    # Example: trying to convert 'abc' to an integer
    num = int('abc')
except (ValueError, TypeError) as error:
    print("Invalid input:", error)

Output:

Invalid input: invalid literal for int() with base 10: 'abc'

Using else Block

The else block executes only if the try block completes without raising any exceptions.

try:
    num = int(input("Enter a number: "))
except ValueError:
    print("That is not a valid number.")
else:
    print("You entered:", num)

Example Interaction:

Enter a number: 42
You entered: 42

Using finally Block

The finally block executes regardless of whether an exception occurred or not. It's typically used for cleanup operations, such as closing files.

try:
    file = open('example.txt', 'r')
    content = file.read()
except FileNotFoundError:
    print("File does not exist.")
finally:
    # This will always execute, whether the file was found or not
    print("Execution completed.")
    # It's good practice to close files here if they were opened
    if 'file' in locals() and file and not file.closed:
        file.close()

Example Output (if example.txt doesn't exist):

File does not exist.
Execution completed.

Raising Exceptions Manually

You can raise exceptions explicitly in your code using the raise keyword. This is useful for signaling specific error conditions or validating inputs.

Syntax

raise ExceptionType("Custom error message")

Example

def divide(a, b):
    if b == 0:
        raise ZeroDivisionError("Cannot divide by zero")
    return a / b

try:
    result = divide(10, 0)
except ZeroDivisionError as err:
    print("Caught Error:", err)

Output:

Caught Error: Cannot divide by zero

Summary of Key Concepts

ConceptDescription
ExceptionAn error that disrupts the normal program flow.
Built-in ExceptionPredefined error classes for common error scenarios in Python.
try-exceptCode blocks used to catch and handle exceptions gracefully.
else BlockExecutes if no exception occurs within the try block.
finally BlockExecutes regardless of whether an exception occurred or was handled.
raiseKeyword used to manually trigger an exception.

Interview Questions

  1. What is an exception in Python? An exception is an event that occurs during program execution that disrupts the normal flow of instructions.

  2. What is the base class for all built-in exceptions in Python? The base class is BaseException.

  3. Name five common built-in exceptions in Python and their causes.

    • TypeError: Operation/function applied to inappropriate type.
    • ValueError: Function receives an argument of correct type but inappropriate value.
    • IndexError: Sequence index out of range.
    • KeyError: Dictionary key not found.
    • ZeroDivisionError: Division by zero.
  4. How does the exception hierarchy in Python work? Exceptions are organized in a tree-like structure, with BaseException at the root. More specific exceptions inherit from broader ones, allowing for flexible error handling by catching either specific errors or their parent classes.

  5. What is the difference between ImportError and ModuleNotFoundError? ImportError is raised when an import statement fails to find a module or a name within a module. ModuleNotFoundError is a subclass of ImportError specifically raised when a module cannot be found.

  6. How do you handle multiple exceptions in a single try-except block? You can list the exception types in a tuple within the except statement: except (ExceptionType1, ExceptionType2) as e:.

  7. Explain the role of the else block in Python’s exception handling. The else block executes if and only if the try block completes without raising any exceptions. It's useful for code that should run only when the try block is successful.

  8. When and why would you use the finally block? The finally block is used for code that must execute regardless of whether an exception occurred or not. It's typically used for cleanup actions, such as closing files, releasing resources, or ensuring certain operations always complete.

  9. How do you manually raise exceptions in Python? Provide an example. Use the raise keyword followed by an exception instance: raise ValueError("Invalid input provided").

    def check_positive(number):
        if number <= 0:
            raise ValueError("Number must be positive")
        print("Number is positive")
    
    try:
        check_positive(-5)
    except ValueError as e:
        print(f"Caught an error: {e}")
  10. What happens if you try to access a list index that is out of range? Which exception is raised? An IndexError is raised.