Python Exceptions

Exceptions in Python are errors that occur during the execution of a program. When Python encounters an error, it stops the execution and raises an exception. Python provides a robust mechanism to handle these exceptions using try, except, and finally blocks. Properly handling exceptions is crucial for building resilient and user-friendly applications.

Common Exceptions

Python has a wide range of built-in exceptions that cover most error cases you might encounter. Here are some of the most common exceptions:

Handling Exceptions

Handling exceptions allows your program to continue running even if an error occurs. The basic structure for handling exceptions in Python involves the try block, which contains the code that might raise an exception, and one or more except blocks that handle the exception:

Python
# Example of handling exceptions
try:
    x = int(input("Enter a number: "))
    result = 10 / x
except ValueError:
    print("Invalid input. Please enter a valid number.")
except ZeroDivisionError:
    print("Cannot divide by zero.")
finally:
    print("Execution complete.")

In this example:

Raising Exceptions

Sometimes you might want to raise an exception deliberately in your code to signal that an error has occurred. You can do this using the raise keyword:

Python
# Example of raising an exception
def check_age(age):
    if age < 18:
        raise ValueError("Age must be at least 18.")
    return "Access granted."

try:
    age = int(input("Enter your age: "))
    print(check_age(age))
except ValueError as e:
    print("Error:", e)

In this example, if the check_age function is called with an age less than 18, it raises a ValueError with a custom error message. The exception is caught by the except block and the error message is printed.

Catching Multiple Exceptions

You can catch multiple exceptions in a single except block by listing them as a tuple:

Python
# Example of catching multiple exceptions
try:
    x = int(input("Enter a number: "))
    y = int(input("Enter another number: "))
    result = x / y
except (ValueError, ZeroDivisionError) as e:
    print("Error:", e)

This code handles both ValueError (if the input is not an integer) and ZeroDivisionError (if the second number is zero) with a single except block.

Custom Exceptions

You can define your own exceptions in Python by creating a new exception class. Custom exceptions are useful for handling specific error conditions in your programs:

Python
# Example of a custom exception
class NegativeNumberError(Exception):
    pass

def check_positive(number):
    if number < 0:
        raise NegativeNumberError("Negative numbers are not allowed.")
    return number

try:
    num = int(input("Enter a positive number: "))
    print(check_positive(num))
except NegativeNumberError as e:
    print("Error:", e)

In this example, the custom exception NegativeNumberError is raised when a negative number is entered. This allows for more precise control over how specific errors are handled in the program.

The else Clause in Exception Handling

Python also supports an else clause in the exception handling block. The else block runs only if no exceptions were raised in the try block:

Python
# Example using the else clause
try:
    x = int(input("Enter a number: "))
    result = 10 / x
except ZeroDivisionError:
    print("Cannot divide by zero.")
else:
    print("Division successful. The result is:", result)
finally:
    print("Execution complete.")

Here, the else block runs only if the division operation is successful, without any exceptions.

Best Practices for Exception Handling

Here are some best practices to follow when handling exceptions in Python:

Conclusion

Exception handling is a crucial aspect of writing robust Python programs. By understanding how to use try, except, else, and finally blocks effectively, and by following best practices, you can ensure that your programs handle errors gracefully and continue running smoothly.