What are Exceptions?

Exceptions are errors that occur during program execution. Instead of crashing, you can catch and handle exceptions to make your program more robust.

Basic try-except

Use try and except to handle errors:

try:
    number = int(input("Enter a number: "))
    result = 10 / number
    print(f"Result: {result}")
except ValueError:
    print("That's not a valid number!")
except ZeroDivisionError:
    print("Cannot divide by zero!")

Multiple Exceptions

Handle different exceptions separately:

try:
    # Code that might raise exceptions
    value = int(input("Enter number: "))
    result = 10 / value
except ValueError:
    print("Invalid input")
except ZeroDivisionError:
    print("Division by zero")
except Exception as e:
    print(f"Unexpected error: {e}")

Catching Multiple Exceptions

Handle multiple exception types in one block:

try:
    # Code here
    pass
except (ValueError, TypeError) as e:
    print(f"Input error: {e}")

else Clause

Execute code when no exception occurs:

try:
    result = 10 / 2
except ZeroDivisionError:
    print("Cannot divide by zero")
else:
    print(f"Result: {result}")  # Only runs if no exception

finally Clause

Always execute code, regardless of exceptions:

try:
    file = open('data.txt', 'r')
    content = file.read()
except FileNotFoundError:
    print("File not found")
finally:
    file.close()  # Always executes, even if error occurs

Raising Exceptions

Raise your own exceptions:

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(e)  # "Cannot divide by zero"

Common Built-in Exceptions

  • ValueError: Wrong value type
  • TypeError: Wrong type
  • IndexError: List index out of range
  • KeyError: Dictionary key not found
  • FileNotFoundError: File doesn't exist
  • ZeroDivisionError: Division by zero
  • AttributeError: Attribute doesn't exist

Custom Exceptions

Create your own exception classes:

class CustomError(Exception):
    pass

class AgeError(Exception):
    def __init__(self, age, message="Age must be positive"):
        self.age = age
        self.message = message
        super().__init__(self.message)

def set_age(age):
    if age < 0:
        raise AgeError(age)
    return age

try:
    set_age(-5)
except AgeError as e:
    print(f"Error: {e.message}, got {e.age}")

Best Practices

  • Be specific: Catch specific exceptions, not all
  • Don't ignore exceptions: At least log them
  • Use finally for cleanup: Close files, connections, etc.
  • Provide helpful messages: Make error messages clear
  • Don't catch everything: Let unexpected errors propagate

Next Steps

Learn about file handling where exception handling is crucial, or explore common Python errors to understand different exception types.