Python Exceptions: Understanding and Handling Errors
Introduction to Python Exceptions
In Python, exceptions are errors that occur during the execution of a program. When Python encounters an error, it raises an exception, which can stop the program from running unless the exception is handled. Exception handling allows us to manage errors gracefully, ensuring that our program can continue running or exit cleanly. This tutorial will focus on examples to help you understand how exceptions work with maximum practical code.
Example 1: Basic Exception Handling
In this example, we attempt to divide a number by zero, which raises a 'ZeroDivisionError'. The 'except' block catches this error and prints an appropriate message, preventing the program from crashing.
Code:
try:
# Attempt to divide by zero, which will raise an exception
result = 100 / 0
except ZeroDivisionError:
# Handle the exception if division by zero occurs
print("Cannot divide by zero!")
Output:
Cannot divide by zero!
Explanation:
- try: This block contains code that might raise an exception.
- except: This block contains the code that runs if the specified exception occurs.
Example 2: Handling Multiple Exceptions
Here, we're trying to access an element at an invalid index in a list, which raises an 'IndexError'. The 'correct' except block catches this error and prints a message. The 'ZeroDivisionError' block is not executed, demonstrating how you can handle multiple specific exceptions.
Code:
try:
# Attempt to access an invalid index in a list
my_list = [1, 2, 3, 4]
print(my_list[5])
except IndexError:
# Handle the exception if an invalid index is accessed
print("Index out of range!")
except ZeroDivisionError:
# This block won't run in this example
print("Cannot divide by zero!")
Output:
Index out of range!
Explanation:
- Multiple 'except' blocks can be used to handle different exceptions separately.
- Python checks each 'except' block in the order they are written.
Example 3: Catching All Exceptions
This example catches all exceptions using the generic Exception class. This is useful when you want to ensure that any error is handled, although it's often better to catch specific exceptions.
Code:
try:
# Attempt an operation that may cause an exception
result = 100 / 0
except Exception as e:
# Catch any exception and print the exception message
print(f"An error occurred: {e}")
Output:
An error occurred: division by zero
Explanation:
- 'Exception' is the base class for all built-in exceptions. By catching 'Exception', you can handle any kind of error.
- 'as e' allows you to capture the exception object and retrieve the error message.
Example 4: Finally Block
In this example, we attempt to open a non-existent file, which raises a 'FileNotFoundError'. The 'finally' block runs regardless of whether the 'try' block was successful or an exception was caught, ensuring that certain code always executes.
Code:
try:
# Try to open a non-existent file
file = open("test.txt", "r")
except FileNotFoundError:
# Handle the exception if the file does not exist
print("File not found!")
finally:
# This block runs no matter what, even if an exception occurred
print("This will always execute, even if an error occurred.")
Output:
File not found! This will always execute, even if an error occurred.
Explanation:
- The 'finally' block runs whether or not an exception occurred, making it ideal for cleanup actions like closing files or releasing resources.
Example 5: Raising Exceptions
In this example, we define a function that checks if the age is less than 18. If it is, a 'ValueError' is raised. The exception is then caught and handled in the 'try-except' block, allowing you to provide a custom error message.
Code:
def check_age(age):
if age < 18:
# Raise a ValueError if the age is less than 18
raise ValueError("Age must be 18 or older.")
else:
print("Age is valid.")
try:
check_age(16) # This will raise an exception
except ValueError as e:
print(f"Error: {e}")
Output:
Error: Age must be 18 or older.
Explanation:
- You can use the 'raise' statement to generate an exception intentionally.
- This is useful when you want to enforce certain conditions within your code.
Example 6: Raising Exceptions
Here, we define a custom exception 'MyCustomError' and raise it within a function. The custom exception is caught and handled in a 'try-except' block, demonstrating how to use exceptions tailored to your specific needs.
Code:
class MyCustomError(Exception):
"""Custom exception for demonstration."""
pass
def some_function():
# Raise the custom exception
raise MyCustomError("Something went wrong!")
try:
some_function()
except MyCustomError as e:
print(f"Caught custom error: {e}")
Output:
Caught custom error: Something went wrong!
Explanation:
- You can create your own exceptions by subclassing the Exception class.
- Custom exceptions are useful for making your code more readable and for handling domain-specific errors.
Example 7: Raising Exceptions
In this example, the division operation is successful, so the 'else' block runs, printing the result. The 'else' block is a way to add logic that should only run if no exceptions occur.
Code:
try:
# Attempt a division that will succeed
result = 100 / 2
except ZeroDivisionError:
print("Cannot divide by zero!")
else:
# This block runs only if no exception occurs
print("Division successful:", result)
Output:
Division successful: 50.0
Explanation:
- The 'else' block is executed only if no exceptions are raised in the 'try' block.
- This can be useful for running code that should only execute when the 'try' block is successful.
- Weekly Trends and Language Statistics
- Weekly Trends and Language Statistics