Python - Raising Exceptions
Hello there, aspiring Pythonistas! Today, we're going to dive into the exciting world of raising exceptions in Python. Don't worry if you're new to programming – I'll guide you through this concept step by step, just like I've done for countless students over my years of teaching. So, grab a cup of your favorite beverage, and let's embark on this Python adventure together!
Raising Exceptions in Python
Imagine you're cooking a delicious meal, but suddenly you realize you're out of a crucial ingredient. What do you do? You'd probably stop cooking and alert everyone about the problem, right? Well, that's exactly what raising exceptions in Python is all about – it's a way to signal that something unexpected or problematic has occurred in your code.
Why Raise Exceptions?
Raising exceptions allows us to:
- Indicate errors or unusual situations
- Control the flow of our program
- Provide meaningful feedback to users or other parts of our code
Let's start with a simple example:
def divide(a, b):
if b == 0:
raise ValueError("Cannot divide by zero!")
return a / b
try:
result = divide(10, 0)
except ValueError as e:
print(f"Oops! An error occurred: {e}")
In this example, we're raising a ValueError
when someone tries to divide by zero. Let's break it down:
- We define a function
divide(a, b)
that checks ifb
is zero. - If
b
is zero, we raise aValueError
with a custom message. - We use a
try-except
block to catch the exception and print a friendly message.
When you run this code, you'll see:
Oops! An error occurred: Cannot divide by zero!
Raising Built-in Exceptions
Python comes with a variety of built-in exceptions that we can raise. Here's a table of some common ones:
Exception | Description |
---|---|
ValueError | Raised when a function receives an argument of the correct type but an inappropriate value |
TypeError | Raised when an operation or function is applied to an object of an inappropriate type |
IndexError | Raised when a sequence subscript is out of range |
KeyError | Raised when a dictionary key is not found |
FileNotFoundError | Raised when a file or directory is requested but doesn't exist |
Let's see some examples:
def check_age(age):
if not isinstance(age, int):
raise TypeError("Age must be an integer")
if age < 0:
raise ValueError("Age cannot be negative")
print(f"Your age is {age}")
try:
check_age("twenty")
except TypeError as e:
print(f"Type error: {e}")
try:
check_age(-5)
except ValueError as e:
print(f"Value error: {e}")
When you run this code, you'll see:
Type error: Age must be an integer
Value error: Age cannot be negative
Raising Custom Exceptions
Sometimes, the built-in exceptions just don't cut it. That's when we create our own custom exceptions! It's like being a chef and creating your own unique recipes.
Creating Custom Exceptions
To create a custom exception, we simply define a new class that inherits from the Exception
class:
class TooManyPizzasError(Exception):
pass
def order_pizza(number):
if number > 100:
raise TooManyPizzasError("Whoa! That's too many pizzas to handle!")
print(f"Order confirmed: {number} pizzas")
try:
order_pizza(101)
except TooManyPizzasError as e:
print(f"Order failed: {e}")
In this delicious example:
- We define a custom exception
TooManyPizzasError
. - Our
order_pizza
function raises this exception if someone orders more than 100 pizzas. - We catch the exception and print a friendly message.
When you run this code, you'll see:
Order failed: Whoa! That's too many pizzas to handle!
Re-Raising Exceptions
Sometimes, you might want to catch an exception, do something with it, and then re-raise it for someone else to handle. It's like passing a hot potato in a game!
Here's how you can do it:
def risky_operation():
print("Starting risky operation...")
raise ValueError("Something went wrong!")
def perform_operation():
try:
risky_operation()
except ValueError:
print("Caught an error, logging it...")
raise # Re-raise the exception
try:
perform_operation()
except ValueError as e:
print(f"Operation failed: {e}")
In this example:
-
risky_operation()
always raises aValueError
. -
perform_operation()
catches the exception, logs it, and then re-raises it. - We catch the re-raised exception in the outer try-except block.
When you run this code, you'll see:
Starting risky operation...
Caught an error, logging it...
Operation failed: Something went wrong!
And there you have it, folks! We've covered raising exceptions, built-in exceptions, custom exceptions, and even re-raising exceptions. Remember, exceptions are not your enemies – they're valuable tools that help you write robust and error-resistant code.
As I always tell my students, coding is like learning to ride a bike. You might fall a few times, but each fall (or exception) teaches you something new. Keep practicing, stay curious, and don't be afraid to raise a few exceptions along the way!
Happy coding, and may your exceptions always be intentional! ?✨
Credits: Image by storyset