What are exceptions in Python
Exceptions in Python are events that occur during the execution of a program and disrupt the normal course of its operation. They allow you to elegantly handle errors and unforeseen situations, making the code more reliable and predictable.
Exception generation using raise
In Python, exceptions can be enforced using the raise operator. This is useful when you need to report a problem or error in the program logic.
# Simple example of exception generation
raise ValueError("Invalid value!")
# Generating an exception with the condition
age = -5
if age < 0:
raise ValueError("Age cannot be negative")
Basics of exception handling: try-except
The try-except construction is the main exception handling mechanism in Python. The code that can cause an exception is placed in the try block, and error handling is placed in the except block.
try:
# Potentially dangerous code
result = 10 / 0
except ZeroDivisionError:
# Handling a specific type of exception
print("Error: division by zero is unacceptable!")
Handling multiple exceptions
Python allows you to handle different types of exceptions using multiple except blocks or a single block for a group of exceptions.
# Multiple blocks except
try:
number = int(input("Enter a number: "))
result = 100 / number
except ValueError:
print("Error: incorrect number entered")
except ZeroDivisionError:
print("Error: division by zero")
# Grouping exceptions
try:
# Some kind of code
pass
except (ValueError, TypeError, ZeroDivisionError) as e:
print(f"Error occurred: {e}")
else block: execution in the absence of exceptions
The else block is executed only if there are no exceptions in the try block. This allows you to separate the logic of successful execution and error handling.
try:
number = int(input("Enter a number: "))
result = 100 / number
except ValueError:
print("Input error: number required")
except ZeroDivisionError:
print("Error: division by zero")
else:
print(f"Calculation result: {result}")
The finally block: guaranteed execution
The finally block is always executed, regardless of whether an exception has occurred or not. It is critical for freeing up resources and completing completion operations.
try:
file = open("data.txt", "r")
content = file.read()
print(content)
except FileNotFoundError:
print("File not found")
except IOError:
print("Error reading the file")
finally:
# The file will be closed anyway
if 'file' in locals():
file.close()
print("File is closed")
Creating custom exceptions
Creating your own exception classes allows you to more accurately describe errors in your application and handle them in a specific way.
class ValidationError(Exception):
"""Exception for data validation errors"""
def __init__(self, message, field=None):
super().__init__(message)
self.field = field
class DatabaseError(Exception):
"""Exception for database errors"""
pass
# Using custom exceptions
def validate_email(email):
if "@" not in email:
raise ValidationError("Invalid email", field="email")
try:
validate_email("invalid-email")
except ValidationError as e:
print(f"Validation error: {e}")
if e.field:
print(f"Problem field: {e.field}")
Getting information about an exception
Python provides several ways to get detailed information about an exception:
import traceback
try:
result = 10 / 0
except Exception as e:
print(f"Exception type: {type(e).__name__}")
print(f"Message: {e}")
print("Full trace:")
traceback.print_exc()
Best Exception Handling Practices
1. Catch specific exceptions: Avoid using a generic exception when it is possible to catch a specific type of exception.
2. Use context managers: To work with files and resources, it is preferable to use with:
try:
with open("file.txt", "r") as file:
content = file.read()
except FileNotFoundError:
print("File not found")
# The file will close automatically
3. Log exceptions: Save error information for later analysis:
import logging
logging.basicConfig(level=logging.ERROR)
try:
risky_operation()
except Exception as e:
logging.error(f"Error in operation: {e}", exc_info=True)
Conclusion
Proper exception handling in Python is a key skill for writing reliable and professional code. Using try-except-else-finally constructs, creating custom exceptions, and following best practices will help you create error-resistant programs that respond correctly to unforeseen situations.