Python Exception Handling Tutorial
This tutorial will guide you through handling exceptions in Python using the `try` and `except` blocks. Exceptions are errors that occur during program execution. Proper exception handling prevents your program from crashing and allows you to gracefully recover from errors. We will explore common scenarios and learn how to handle them effectively.
Understanding Try and Except
The `try` block contains the code that might raise an exception. The `except` block specifies how to handle a specific type of exception that might be raised within the `try` block. You can have multiple `except` blocks to handle different types of exceptions.
Example 1: Handling ZeroDivisionError
This example demonstrates handling the `ZeroDivisionError`, which occurs when you try to divide a number by zero.
def safe_division(numerator, denominator):
try:
result = numerator / denominator
print(f"The result of {numerator} / {denominator} is: {result}")
except ZeroDivisionError:
print("Error: Division by zero is not allowed.")
result = None # Set a default value in case of error
return result
# Test cases
safe_division(10, 2)
safe_division(5, 0)
safe_division(15, 3)
Let’s break down the code:
- We define a function `safe_division` that takes two arguments, `numerator` and `denominator`.
- Inside the `try` block, we attempt to calculate the result of the division.
- If a `ZeroDivisionError` occurs (i.e., `denominator` is 0), the code jumps to the first `except` block.
- In the `except` block, we print an error message and set the `result` to `None` to indicate that the division failed.
- The function returns the `result`.
Common mistake: Forgetting to include the `except` block. If no `except` block exists, the program will halt when an exception occurs.
Correction: Always include an `except` block to handle potential errors gracefully.
# Output
# The result of 10 / 2 is: 5.0
# Error: Division by zero is not allowed.
# The result of 5 / 0 is: None
# The result of 15 / 3 is: 5.0
Example 2: Handling ValueError
This example demonstrates handling the `ValueError`, which occurs when a function receives an argument of the correct data type but an inappropriate value. Let’s use a simple mathematical function.
def calculate_square_root(number):
try:
result = number 0.5
print(f"The square root of {number} is: {result}")
except ValueError:
print(f"Error: Cannot calculate the square root of a negative number ({number}).")
result = None
return result
# Test cases
calculate_square_root(9)
calculate_square_root(-1)
calculate_square_root(16)
This example calculates the square root of a given number. The `ValueError` is raised if the input number is negative.
# Output
# The square root of 9 is: 3.0
# Error: Cannot calculate the square root of a negative number (-1).
# The square root of 16 is: 4.0
Example 3: Combining Multiple Exception Handling
This example demonstrates handling both `ZeroDivisionError` and `ValueError` within a single `try` block.
def robust_division(numerator, denominator):
try:
result = numerator / denominator
print(f"The result is: {result}")
except ZeroDivisionError:
print("Error: Division by zero is not allowed.")
except ValueError:
print("Error: Invalid input. Numerator and denominator must be numbers.")
except Exception as e: # Catches any other exception
print(f"An unexpected error occurred: {e}")
return result
# Test cases
robust_division(10, 2)
robust_division(5, 0)
robust_division("hello", 2)
robust_division(10, "world")
Here, we’ve added a broader `except Exception as e:` to catch any unexpected errors. This is good practice for robust code.
# Output
# The result is: 5.0
# Error: Division by zero is not allowed.
# Error: Invalid input. Numerator and denominator must be numbers.
# Error: Invalid input. Numerator and denominator must be numbers.
Key takeaway: Exception handling is crucial for writing stable and reliable Python code. By anticipating potential errors and handling them appropriately, you can prevent your programs from crashing and provide a better user experience.



Leave a Reply