Reading and Writing Files

Save and load data that outlives your program

Beginner 11 min

In this lesson

Reading and writing files is how a Python program saves data that outlives a single run — because variables vanish when your program ends. This lesson covers reading from and writing to text files, the foundation of saving and loading information.

Explain it like I’m 5

A file is a notebook on disk. Your program can open it to read what’s written, or open it to write new things down — and unlike a variable, what’s in the notebook is still there tomorrow.

Opening files with with

The right way to open a file is the with statement: with open("notes.txt") as f:. The with block automatically closes the file when you’re done — even if an error occurs — so you never leak open files. Always use with; manually calling open() and close() is error-prone.

Example
# Run this locally — it creates a file on your computer.
with open("notes.txt", "w") as f:
    f.write("Saved from Python!\n")
# Outside the block, the file is already closed for you.
print("File written and closed.")
Output
File written and closed.
Open, write, and auto-close in one block. (Run locally.)

Read modes and write modes

The second argument to open is the mode: "r" read (the default), "w" write (creates the file, or erases existing contents), "a" append (adds to the end without erasing). Choosing the wrong mode is a classic mistake — "w" will silently wipe a file you meant only to read.

Example
# "a" adds to the end without erasing what's there.
with open("log.txt", "a") as f:
    f.write("ran the report\n")

print("Appended one line to the log.")
Output
Appended one line to the log.
Append mode keeps existing content. (Run locally.)

Reading text

f.read() returns the whole file as one string. f.readlines() gives a list of lines. Most often you loop directly: for line in f: reads one line at a time, which is memory-friendly for big files. Lines include their trailing newline, so line.strip() is handy to clean them up.

Example
# Assume greetings.txt contains two lines: Hello and World.
with open("greetings.txt", "r") as f:
    for line in f:
        print(line.strip())
Output
Hello
World
Loop over a file one line at a time. (Run locally.)

Writing text

Open with "w" or "a" and call f.write("some text"). Unlike print, write does not add a newline, so include \n yourself when you want line breaks. Everything you write is text; convert numbers with str() first.

Example
# Numbers must be turned into text before writing.
with open("scores.txt", "w") as f:
    for n in [90, 75, 88]:
        f.write(str(n) + "\n")

print("Wrote 3 scores, one per line.")
Output
Wrote 3 scores, one per line.
Convert numbers with str() and add your own \n. (Run locally.)

Encoding, and structured formats (JSON, CSV)

Two practical notes for real-world files. First, encoding: open text files with encoding="utf-8" so accented letters and emoji read correctly everywhere — open("notes.txt", encoding="utf-8"). Leaving it out can give different results on different machines.

Second, you rarely invent your own file format. The standard library’s json module handles nested data and csv handles spreadsheet rows — both via import. The example below uses json without touching a file, so it runs right here; to actually save the result, write the text to a file as shown earlier (and find it with pathlib).

Example
import json

data = {"name": "Ada", "topics": ["loops", "lists"]}
text = json.dumps(data)
print(text)

restored = json.loads(text)
print(restored["topics"])
Output
{"name": "Ada", "topics": ["loops", "lists"]}
['loops', 'lists']
json turns Python data into text and back again.

Common mistake: Forgetting to use with (and leaving files open)

Why it happens:

Calling open() without with means you must remember to close() — and if an error happens first, the file stays open.

How to fix it:

Always use with open(...) as f:. The file closes automatically at the end of the block, even on errors.

with open("data.txt") as f:
    contents = f.read()
# file is closed here automatically

Common mistake: Opening with "w" when you meant to read

Why it happens:

"w" looks harmless but truncates the file to empty before you do anything.

How to fix it:

Use "r" (or omit the mode) to read. Reserve "w" for when you intend to replace the file’s contents.

Why use 'with' when opening a file?

Which mode ERASES an existing file's contents when opened?

Mini exercise (medium)

Locally, write the numbers 1 to 5 to numbers.txt, one per line, then read the file back and print the total of all the numbers.

Real files need your own computer, so here we keep the text in memory — the read-back-and-total logic is identical. Build the lines, then total the numbers.

# Build the "file" text: numbers 1..5, one per line
text = "\n".join(str(n) for n in range(1, 6))

# Now read it back and total the numbers:
total = 0
for line in text.splitlines():
    pass  # TODO: add int(line) to total
print(total)

What to learn next

You learned to open files, why the with statement matters, how to read and write text, the different file modes, and how to loop over lines. You built a block of text in memory, then read it back line by line and totalled the numbers.

Once you’re working with files, you need to point at them reliably, even across different operating systems. Paths and Folders covers absolute versus relative paths, the working directory, and using pathlib to join paths safely. When you’re ready, continue to the next lesson.