Most real programs need to save data between runs. Python's built-in file handling makes this straightforward, without needing a database for simple cases.

Writing to a file

with open("notes.txt", "w") as f:
    f.write("Learning Python file handling\n")
    f.write("Second line\n")

The with statement automatically closes the file when the block finishes, even if an error happens partway through - always prefer it over manually calling f.close().

Reading a file

with open("notes.txt", "r") as f:
    for line in f:
        print(line.strip())   # .strip() removes the trailing newline

Appending instead of overwriting

Opening a file with mode "w" erases its previous contents. Use "a" (append) to add to the end without deleting what is already there:

with open("notes.txt", "a") as f:
    f.write("This gets added at the end\n")

A practical pattern: saving structured data

def add_expense(category, amount):
    with open("expenses.txt", "a") as f:
        f.write(f"{category},{amount}\n")

def total_expenses():
    total = 0
    with open("expenses.txt", "r") as f:
        for line in f:
            category, amount = line.strip().split(",")
            total += float(amount)
    return total

add_expense("Food", 250)
add_expense("Travel", 100)
print("Total spent:", total_expenses())

This exact pattern - one line of text per record, comma-separated - is the foundation of the expense tracker project in our Python tutorial on the blog.