The try-except-finally construct in Python is used to handle exceptions—errors that occur during program execution. It helps you gracefully deal with errors, preventing your program from crashing unexpectedly.

Why use try-except ?

In programming, errors can happen for many reasons:
• A file might not exist.
• A user might input invalid data.
• A calculation might involve division by zero.

Instead of letting the program crash, try-except allows you to:
1. Detect the error.
2. Handle it appropriately.
3. Optionally, clean up resources using finally.

Structure

try:
    # Code that might raise an exception
except ExceptionType:
    # Code to handle the exception
finally:
    # Code that runs no matter what (optional)

• try: The block where you write code that might raise an error.
• except: The block to handle the error if it occurs.
• finally: (Optional) The block that always executes, whether an error occurs or not.

Examples on try-except-finally in python

Imagine you're cooking a dish:
1. try: You attempt to cook (the main code).
2. except: If you accidentally burn the dish (an error), you handle it by ordering food.
3. finally: Afterward, you clean up the kitchen regardless of success or failure.

Examples 1. Handling a Common Error (Division by Zero)

try:
    num = int(input("Enter a number: "))
    result = 10 / num
    print(f"Result: {result}")
except ZeroDivisionError:
    print("You cannot divide by zero!")
except ValueError:
    print("Please enter a valid number.")
finally:
    print("Operation complete.")

How It Works:
• If the user enters 0 → ZeroDivisionError occurs, and the message is printed.
• If the user enters invalid data (like "abc") → ValueError occurs.
• The finally block always executes.

Example 2 . Real-Life: Reading a File

try:
    file = open("example.txt", "r")
    content = file.read()
    print(content)
except FileNotFoundError:
    print("The file does not exist.")
finally:
    print("Closing the file.")
Output:

• If the file exists, its content is displayed.
• If the file doesn't exist, FileNotFoundError is handled.
• The finally block executes regardless, ensuring cleanup.

Example 3. Handling Multiple Exception Types

try:
    num1 = int(input("Enter first number: "))
    num2 = int(input("Enter second number: "))
    result = num1 / num2
    print(f"Result: {result}")
except ZeroDivisionError:
    print("Cannot divide by zero!")
except ValueError:
    print("Invalid input. Please enter numbers only.")
except Exception as e:  # Catch-all for unexpected errors
    print(f"An unexpected error occurred: {e}")
finally:
    print("Thanks for using the calculator!")
Output:
•	Handles division by zero, invalid input, or any other unexpected error.

Example 4. Nested Try-Except (Real-Life: ATM Withdrawal)

try:
    balance = 1000
    amount = int(input("Enter amount to withdraw: "))
    try:
        if amount > balance:
            raise ValueError("Insufficient funds!")
        print(f"Withdrawal successful. Remaining balance: {balance - amount}")
    except ValueError as e:
        print(e)
except Exception as e:
    print(f"Error: {e}")
finally:
    print("Transaction complete.")

Key Concept:

• Nested try-except allows handling specific parts of the logic independently.

finally for Resource Cleanup
The finally block is commonly used to release resources like files, database connections, or network connections.

try:
    connection = open("data.db", "r")
    # Perform operations
except FileNotFoundError:
    print("Database file not found.")
finally:
    connection.close()
    print("Connection closed.")

Best Practices

1. Be Specific in except:
o Catch specific errors (e.g., ZeroDivisionError) rather than using a generic Exception.
o This ensures you only handle expected issues.
2. Keep try Blocks Short:
o Focus on code that might raise an exception; don’t include unnecessary logic.
3. Use else (Optional):
o The else block executes if no exceptions occur.

try:
    result = 10 / 2
except ZeroDivisionError:
    print("Error!")
else:
    print(f"Success: {result}")
finally:
    print("Done.")

4. Log Errors:
o In real-world applications, log exceptions for debugging instead of just printing them.

Key Takeaways

• try: Protects risky code.
• except: Handles errors gracefully.
• finally: Ensures cleanup or final actions.

This structure ensures your program can recover from unexpected situations without breaking.