Python's exceptions can be categorized into several groups based on their types and common use cases. Here's a categorization of exceptions along with detailed explanations and expert-level examples of exception handling using try
, except
, else
, and finally
blocks.
Common Exception Categories:
Whatever exceptions explained in basic are handled here with try
and except
1. Syntax Errors
SyntaxError
: Raised when there is a syntax error in the code.
try:
eval("1 + * 2")
except SyntaxError as e:
print(f"SyntaxError: {e}")
2. Name Errors
NameError
: Raised when a local or global name is not found.
try:
print(undefined_variable)
except NameError as e:
print(f"NameError: {e}")
3. Type Errors
TypeError
: Raised when an operation or function is applied to an object of inappropriate type.
try:
result = "5" + 3
except TypeError as e:
print(f"TypeError: {e}")
4. Value Errors
ValueError
: Raised when a built-in operation or function receives an argument of the correct type but inappropriate value.
try:
int("abc")
except ValueError as e:
print(f"ValueError: {e}")
5. Index Errors
IndexError
: Raised when trying to access an index that is out of range in a sequence.
try:
my_list = [1, 2, 3]
print(my_list[5])
except IndexError as e:
print(f"IndexError: {e}")
6. File Errors
FileNotFoundError
: Raised when trying to open or manipulate a file that does not exist.
try:
with open("nonexistent.txt", "r") as file:
content = file.read()
except FileNotFoundError as e:
print(f"FileNotFoundError: {e}")
7. Arithmetic Errors
ZeroDivisionError
: Raised when trying to divide by zero.
try:
result = 10 / 0
except ZeroDivisionError as e:
print(f"ZeroDivisionError: {e}")
8. Key Errors
KeyError
: Raised when trying to access a dictionary key that does not exist.
try:
my_dict = {"name": "Alice", "age": 30}
print(my_dict["address"])
except KeyError as e:
print(f"KeyError: {e}")
Exception Handling with try
, except
, else
, and finally
Python provides a robust way to handle exceptions using try
, except
, else
, and finally
blocks.
try
: The code inside the try
block is the code that might raise an exception.
except
: The code inside the except
block is executed if an exception occurs in the try
block.
else
: The code inside the else
block is executed if no exceptions occur in the try
block.
finally
: The code inside the finally
block is always executed, regardless of whether an exception occurred or not. It's typically used for cleanup tasks.
try:
# Code that might raise an exception
result = 10 / 0
except ZeroDivisionError as e:
# Handle the exception
print(f"ZeroDivisionError: {e}")
else:
# Code to execute if no exception occurred
print("No exception occurred.")
finally:
# Cleanup code (always executed)
print("Cleanup code.")
Expert-Level Example
Suppose you're reading data from a file, and you want to gracefully handle potential exceptions:
try:
# Attempt to read data from a file
with open("data.txt", "r") as file:
data = file.read()
except FileNotFoundError as e:
# Handle the case when the file does not exist
print(f"File not found: {e}")
except PermissionError as e:
# Handle the case when there's a permission issue
print(f"Permission error: {e}")
except Exception as e:
# Handle other exceptions
print(f"An error occurred: {e}")
else:
# Process the data if no exceptions occurred
print("Data read successfully.")
finally:
# Cleanup code (e.g., close the file or release resources)
print("Cleanup code.")
In this expert-level example, we handle various potential exceptions that may occur when reading data from a file, including FileNotFoundError
, PermissionError
, and a general Exception
. The else
block is used to process the data if no exceptions occur, and the finally
block is used for cleanup tasks. This approach ensures robust and graceful handling of exceptions while dealing with file operations.