Built-In Exceptions

Let’s talk about built-in exceptions in Python but with a twist. To begin with: what are exceptions? In programming, an exception is basically when something goes wrong that wasn’t expected or planned for in your code. It can be a syntax error (which we’ll cover later), but most of the time, it’s just some unexpected behavior that causes Python to raise an exception and stop running your script. But don’t worry! With built-in exceptions, you can catch these errors and handle them in a way that makes sense for your program. Let’s take a look at how this works with the following example:

# This function is used to perform some Linux operations
def linux_interaction():
    try:
        # Attempt to open a file called "file.log" in read mode
        open("file.log", "r")
    # If the file is not found, catch the FileNotFoundError exception
    except FileNotFoundError:
        # Print an error message
        print("Oops! The file doesn't exist.")

In this code, we have a function called `linux_interaction()` that does something on a Linux machine (we’ll assume for now). Inside the try block, we attempt to open a file named “file.log” in read mode using Python’s built-in `open()` function.

But what if this file doesn’t exist? That’s where exceptions come into play! If the file isn’t found, then Python will raise a `FileNotFoundError`. However, we can catch that error with an except block and handle it in a way that makes sense for our program. In this case, we simply print out a message to let the user know what happened.

Now, you might be wondering: why bother catching exceptions? Can’t I just let Python crash if something goes wrong? Well, sure! But sometimes you need your code to keep running even when things don’t go as planned. For example, imagine that you have a program that interacts with a database and needs to perform some actions based on the results of those interactions. If there’s an error connecting to the database or retrieving data from it, then you might want to handle that exception in a way that doesn’t cause your entire script to crash.

That’s where finally comes into play! This keyword allows you to execute some code regardless of whether or not an exception was raised inside the try block. Here’s an example:

# This function interacts with a database and handles any potential exceptions that may occur
def database_interaction():
    try:
        # Do some database stuff here...
        cursor = db.cursor() # Creates a cursor object to execute SQL commands
        cursor.execute("SELECT * FROM table") # Executes a SQL query to select all data from a table
        results = cursor.fetchall() # Fetches all the results from the executed query
    except Exception as e: # Catches any exception that may occur and stores it in the variable 'e'
        print(f"Oops! Something went wrong with the database: {e}") # Prints an error message with the exception
    finally:
        db.close() # Closes the database connection, regardless of whether or not an exception was raised

In this code, we have a function called `database_interaction()` that does something with a database (again, assuming for now). Inside the try block, we attempt to execute some SQL statements and retrieve data from them using Python’s built-in `cursor` object. If an exception is raised inside the try block, then we catch it in the except block and print out a message that includes the error details.

But what if there was no exception? In that case, we still want to clean up after ourselves by closing the database connection using Python’s built-in `close()` function. This is where finally comes into play! The code inside this keyword will always execute regardless of whether or not an exception was raised in the try block.

Finally, creating custom exceptions in Python. While there are many built-in exceptions that cover most common use cases, sometimes you need something more specific to your program. For example, imagine a function called `platform_interaction()` that does some platform-specific stuff (like checking the operating system or displaying a message based on it). If an error occurs during this interaction, then you might want to raise a custom exception with a descriptive name:

# Define a custom exception class called PlatformException
class PlatformException(Exception):
    """Raised when there's an issue interacting with the platform."""

# Define a function called linux_interaction that will perform platform-specific tasks
def linux_interaction():
    try:
        # Do some Linux stuff here...
        open("file.log", "r") # Open a file called "file.log" in read mode
    except FileNotFoundError:
        # If the file is not found, raise a PlatformException with a descriptive message
        raise PlatformException("Oops! The file doesn't exist on this platform.")

In this code, we define a custom exception called `PlatformException` that inherits from Python’s built-in Exception class. This allows us to create our own exceptions with descriptive names and messages. In the example above, if an error occurs while trying to open “file.log” on a Linux machine (which is assumed for this function), then we raise a custom `PlatformException` that includes a message specific to the platform.

And there you have it! Remember, don’t take yourself too seriously when writing code sometimes a little bit of sarcasm can go a long way!

SICORPS