Lesson 9: Python File Handling and Exception Handling

⏱️ 3 min read

Up until now, every time your Python program finishes running, all the variables and data disappear. If you want to save that information permanently, your program needs to know how to interact with files on your computer.

Furthermore, when your program interacts with the outside world—like trying to open a file that does not exist or asking a user for a number and getting text instead—things can go wrong. If you do not prepare for these issues, your program will crash.

Here is how you handle reading/writing files and catching errors gracefully in Python.

1. Python File Handling (Saving and Loading Data)

To work with a file in Python, you follow three basic steps: open the file, perform an action (read or write), and close the file.

When you open a file, you must specify a mode that tells Python what you intend to do:

  • 'r' (Read): Opens a file for reading. (Default)
  • 'w' (Write): Opens a file for writing. Warning: This will overwrite any existing data in the file!
  • 'a' (Append): Opens a file to add new data to the very end without erasing the old data.

The Old Way vs. The Better Way: You can use file = open("data.txt", "r") and then file.close(), but if your program crashes before it hits the close() command, the file can get corrupted.

Instead, professional Python developers use the with statement. It automatically closes the file for you as soon as the block of code finishes, even if an error occurs.

Example: Writing to a file

# The 'w' mode creates the file if it doesn't exist, or overwrites it if it does
with open("user_data.txt", "w") as file:
    file.write("Name: Alice\n")
    file.write("Role: Admin\n")

print("Data successfully saved!")

Example: Reading from a file

# The 'r' mode is for reading
with open("user_data.txt", "r") as file:
    content = file.read()
    print("Here is the file content:")
    print(content)

2. Exception Handling (Preventing Crashes)

An exception is just an error that occurs while your program is running. For example, if you try to divide a number by zero, Python doesn’t know what to do, so it throws a ZeroDivisionError and stops the program dead in its tracks.

To prevent your program from crashing, you can “catch” these exceptions using a try and except block.

The Syntax: You put the risky code inside the try block. If it works, great! If it fails, Python skips the rest of the try block and immediately runs the code in the except block instead of crashing.

numerator = 10
denominator = 0

try:
    # This is the risky code
    result = numerator / denominator
    print("The result is:", result)

except ZeroDivisionError:
    # This code only runs if a ZeroDivisionError happens
    print("Error: You cannot divide a number by zero!")

print("The program is still running smoothly.")

Catching Specific Errors: It is a good practice to specify exactly which error you are expecting. You can even chain multiple except blocks together to handle different problems in different ways.

try:
    with open("missing_config.txt", "r") as file:
        data = file.read()

except FileNotFoundError:
    print("Error: The file 'missing_config.txt' was not found.")
    print("Loading default configuration instead...")

except Exception as e:
    # This is a catch-all for any other unexpected error
    print("An unknown error occurred:", e)

The finally Block (The Clean-Up Crew): Sometimes you have code that absolutely must run, regardless of whether an error occurred or not. You can put this in a finally block at the very end.

try:
    print("Attempting to connect to the database...")
    # Imagine some database connection code here that fails
    result = 10 / 0 

except ZeroDivisionError:
    print("A calculation error occurred.")

finally:
    # This will run no matter what happens above
    print("Closing the database connection.")

Ready to continue?

Move on to the next lesson to keep learning.

Continue: Lesson 10: Introduction to Object-Oriented Programming (OOP)

Tutorial: Python