Understanding Exceptions
Exceptions are errors that occur during program execution (runtime errors). Unlike syntax errors, which are detected before the program runs, exceptions occur when the program is running and encounters an unexpected situation.
What are Exceptions?
An exception is an event that disrupts the normal flow of a program’s execution. When an exception occurs, Python creates an exception object that contains information about what went wrong.
Exceptions vs Syntax Errors
Syntax Errors: These are detected by Python before the program runs. They occur when the code doesn’t follow Python’s syntax rules.
# Syntax Error - missing colondef greet(name) print(f"Hello, {name}!")Exceptions: These occur during program execution when something goes wrong, even though the syntax is correct.
# This code has correct syntax but will raise an exceptionx = 10 / 0 # ZeroDivisionErrorCommon Built-in Exceptions
Python provides many built-in exception types. Here are some of the most common ones:
ZeroDivisionError
Raised when attempting to divide by zero:
result = 10 / 0 # ZeroDivisionError: division by zeroValueError
Raised when a function receives an argument of the correct type but with an inappropriate value:
x = int("abc") # ValueError: invalid literal for int() with base 10: 'abc'TypeError
Raised when an operation or function is applied to an object of inappropriate type:
result = "hello" + 5 # TypeError: can only concatenate str (not "int") to strIndexError
Raised when trying to access an index that doesn’t exist in a sequence:
my_list = [1, 2, 3]print(my_list[5]) # IndexError: list index out of rangeKeyError
Raised when trying to access a dictionary key that doesn’t exist:
my_dict = {"name": "Alice", "age": 30}print(my_dict["city"]) # KeyError: 'city'AttributeError
Raised when trying to access an attribute or method that doesn’t exist:
my_list = [1, 2, 3]my_list.appendd(4) # AttributeError: 'list' object has no attribute 'appendd'FileNotFoundError
Raised when trying to open a file that doesn’t exist:
with open("nonexistent.txt", "r") as f: content = f.read() # FileNotFoundError: [Errno 2] No such file or directory: 'nonexistent.txt'Exception Hierarchy
All exceptions in Python inherit from the BaseException class. The most common base class for user-defined exceptions is Exception, which itself inherits from BaseException.
BaseException ├── Exception │ ├── ArithmeticError │ │ └── ZeroDivisionError │ ├── LookupError │ │ ├── IndexError │ │ └── KeyError │ ├── ValueError │ ├── TypeError │ └── ... └── ...Why Handle Exceptions?
Handling exceptions allows your program to:
- Continue running even when errors occur
- Provide meaningful error messages to users
- Clean up resources (close files, connections, etc.)
- Log errors for debugging
- Gracefully degrade functionality when something goes wrong
Exercises
Exercise 1: Identify Exception Types
Write code that demonstrates each of the following exceptions: ZeroDivisionError, ValueError, TypeError, IndexError, and KeyError. For each exception, print a message indicating which exception occurred.
Identify Exception Types
# ZeroDivisionErrortry: result = 10 / 0except ZeroDivisionError: print("ZeroDivisionError occurred")
# ValueErrortry: x = int("abc")except ValueError: print("ValueError occurred")
# TypeErrortry: result = "hello" + 5except TypeError: print("TypeError occurred")
# IndexErrortry: my_list = [1, 2, 3] print(my_list[5])except IndexError: print("IndexError occurred")
# KeyErrortry: my_dict = {"name": "Alice"} print(my_dict["age"])except KeyError: print("KeyError occurred")Exercise 2: Safe List Access
Write a function safe_get_item that takes a list and an index. If the index is valid, return the item at that index. If the index is out of range, return None instead of raising an IndexError. Read the list size, then the list elements, then the index to access.
Safe List Access
def safe_get_item(my_list, index): try: return my_list[index] except IndexError: return None
n = int(input())my_list = []for i in range(n): my_list.append(int(input()))
index = int(input())result = safe_get_item(my_list, index)print(result)