what is Exception Handling?
Exception handling allows you to manage unexpected errors that occur during program execution by using try, except, else, and finally blocks.
Why Use Exception Handling in I/O?
Basic Exception Handling Syntax
try:
# Code that might raise an exception
risky_operation()
except ExceptionType:
# Code to handle the exception
handle_exception()
else:
# Code to run if no exception occurs
success_operation()
finally:
# Code that runs no matter what (cleanup actions)
cleanup()
Common I/O Errors
- FileNotFoundError: File doesn't exist.
- PermissionError: Insufficient permissions to access the file.
- IsADirectoryError: Tried to open a directory instead of a file.
- IOError: General I/O-related error.
Examples-of-Exception-Handling-During-I/O
1. Reading a File
Example: Gracefully handling the case when a file doesn't exist.
try:
with open("nonexistent_file.txt", "r") as file:
content = file.read()
print(content)
except FileNotFoundError:
print("Error: The file does not exist.")
except PermissionError:
print("Error: You do not have permission to read the file.")
else:
print("File read successfully!")
finally:
print("Finished file operation.")
2. Writing to a File
Example: Handling errors during file writing.
try:
with open("output.txt", "w") as file:
file.write("Hello, World!")
print("Data written to file.")
except PermissionError:
print("Error: Insufficient permissions to write to the file.")
except IOError as e:
print(f"An I/O error occurred: {e}")
else:
print("File written successfully.")
finally:
print("File operation completed.")
3. Using finally for Cleanup
Example: Closing a file explicitly to ensure proper resource management.
file = None
try:
file = open("example.txt", "r")
content = file.read()
print(content)
except FileNotFoundError:
print("Error: File not found.")
finally:
if file:
file.close()
print("File closed.")
4. Nested Exception Handling
Example: Handling different exceptions separately.
try:
filename = "data.txt"
mode = "x" # "x" mode creates a file, raises error if file exists
with open(filename, mode) as file:
file.write("Some data")
except FileExistsError:
print("Error: The file already exists.")
except IOError as e:
print(f"General I/O error: {e}")
else:
print("File written successfully!")
5. Catch-All Exception Handling
Example: Using a general except block to catch unexpected exceptions.
try:
with open("file.txt", "r") as file:
content = file.read()
except Exception as e:
print(f"An unexpected error occurred: {e}")
Real-Life Scenarios
Scenario 1: Logging ErrorsIf file operations fail, log the error instead of crashing the program.
import logging
logging.basicConfig(filename="errors.log", level=logging.ERROR)
try:
with open("logfile.txt", "r") as file:
content = file.read()
except Exception as e:
logging.error(f"An error occurred: {e}")
Scenario 2: Retry Logic
Retry a file operation a limited number of times if it fails.
import time
retries = 3
for attempt in range(retries):
try:
with open("important_data.txt", "r") as file:
print(file.read())
break
except FileNotFoundError:
print(f"Attempt {attempt + 1}: File not found. Retrying...")
time.sleep(1)
except Exception as e:
print(f"An error occurred: {e}")
break
else:
print("Failed after multiple attempts.")
Scenario 3: Processing Multiple Files
Handle errors for individual files without halting the entire operation.
files = ["file1.txt", "file2.txt", "file3.txt"]
for file_name in files:
try:
with open(file_name, "r") as file:
print(f"Contents of {file_name}:")
print(file.read())
except FileNotFoundError:
print(f"Error: {file_name} not found.")
except Exception as e:
print(f"Error while processing {file_name}: {e}")
Best Practices
1. Use Specific Exceptions:Catch only the exceptions you expect, like FileNotFoundError, rather than a generic Exception.
2. Use Context Managers (with Statement):Automatically handles file closing.
Example: with open("file.txt", "r") as file:
3. Log Errors Instead of Printing:
Use the logging module for better error tracking.
4. Avoid Silencing Exceptions:o Catch and handle exceptions meaningfully instead of suppressing them.
5. Use finally for Cleanup:o Ensure resources like file handles are released.
Summary
• What You Learned:o Python's exception handling mechanism (try, except, finally) is crucial for robust I/O operations.
o Handle specific I/O errors like FileNotFoundError, PermissionError, and IOError.
o Reading from and writing to files.
o Logging and retry mechanisms.
o Handling multiple files gracefully.