Exception Handling Patterns
Basic Exception Handling
Python provides a robust mechanism for handling unexpected events and errors through exception handling. The core structure involves try
, except
, else
, and finally
blocks.
def divide_numbers(a, b):
try:
result = a / b
except ZeroDivisionError:
print("Cannot divide by zero!")
result = None
except TypeError:
print("Invalid input types")
result = None
else:
print("Division successful")
finally:
print("Execution completed")
return result
Exception Handling Patterns
1. Specific Exception Handling
def read_file(filename):
try:
with open(filename, 'r') as file:
content = file.read()
except FileNotFoundError:
print(f"File {filename} not found")
content = None
except PermissionError:
print(f"Permission denied for {filename}")
content = None
return content
2. Multiple Exception Handling
def complex_operation(data):
try:
## Multiple potential exceptions
result = process_data(data)
value = int(result)
return value
except (ValueError, TypeError) as e:
print(f"Conversion error: {e}")
except Exception as e:
print(f"Unexpected error: {e}")
Exception Hierarchy
graph TD
A[BaseException] --> B[SystemExit]
A --> C[KeyboardInterrupt]
A --> D[Exception]
D --> E[ArithmeticError]
D --> F[TypeError]
D --> G[ValueError]
Exception Handling Strategies
Strategy |
Description |
Use Case |
Specific Handling |
Catch known exceptions |
Predictable error scenarios |
Generic Handling |
Catch all exceptions |
Unexpected error scenarios |
Logging |
Record exception details |
Debugging and monitoring |
Reraise |
Propagate exceptions |
Complex error management |
Custom Exception Handling
class CustomValidationError(Exception):
def __init__(self, message, code):
self.message = message
self.code = code
super().__init__(self.message)
def validate_input(value):
try:
if value < 0:
raise CustomValidationError("Negative value not allowed", 400)
except CustomValidationError as e:
print(f"Error: {e.message}, Code: {e.code}")
Advanced Exception Techniques
Context Managers
class ResourceManager:
def __enter__(self):
print("Acquiring resource")
return self
def __exit__(self, exc_type, exc_value, traceback):
print("Releasing resource")
if exc_type is not None:
print(f"An exception occurred: {exc_type}")
return False
with ResourceManager() as rm:
## Resource management
pass
Best Practices
- Be specific with exception types
- Avoid catching all exceptions indiscriminately
- Use meaningful error messages
- Log exceptions for debugging
- LabEx recommends clean, informative error handling
- Exception handling has performance overhead
- Use exceptions for exceptional circumstances
- Avoid using exceptions for control flow