Skip to content

Intermediate · Working with data · topic 30 of 50 · 20 min

Working with files

Explanation

open() connects your program to a file so you can read it or write to it. Mode "r" reads, "w" writes a fresh file and "a" adds to the end. Always use with open(...) as f: so the file is closed for you, and pass encoding="utf-8" so Hindi and other scripts work.

Why files?

When a program stops, its variables are gone. Files keep data safe on the disk: notes, logs, price lists, marks. Note: on this website Python runs inside your browser and cannot open the files on your computer, so the examples that use real files are shown as text. You can run them in Python on your own computer.

output
f = open("notes.txt", "r", encoding="utf-8")
text = f.read()
f.close()
print(text)
The basic idea: open, read, close. The with statement below does the closing for you.
ModeMeansIf the file existsIf it does not exist
"r"read (the default)reads itFileNotFoundError
"w"writeEMPTIES it firstcreates it
"a"append (add to the end)keeps the old text, adds after itcreates it
Careful: Mode "w" wipes the file the moment you open it, before you write anything. Use "a" to add to a log or a diary. Use "w" only when you really want to replace the whole file.

The with statement

output
with open("expenses.txt", "a", encoding="utf-8") as f:
    f.write("Milk,60\n")
    f.write("Bus ticket,25\n")
# here the file is already closed, even if an error happened inside
write does not add a new line by itself; put at the end.
Think of it like this: with is like borrowing a book from the school library with a strict librarian. However you leave the reading room, normally or in a hurry, the librarian takes the book back and puts it on the shelf. with always closes the file, even when an error happens inside.

Three ways to read

output
with open("marks.txt", encoding="utf-8") as f:
    everything = f.read()        # the whole file as one string

with open("marks.txt", encoding="utf-8") as f:
    first = f.readline()         # one line, with "\n" at the end

with open("marks.txt", encoding="utf-8") as f:
    for line in f:               # best for big files: one line at a time
        print(line.rstrip("\n"))
Looping over the file is the usual way to read line by line.

io.StringIO: a file that lives in memory

io.StringIO takes a string and gives you an object that behaves like an open text file: it has read, readline, write, and you can loop over its lines. So a function that works with a StringIO also works with a real file from open(). That is how we practise files on this website.

python
import io
f = io.StringIO("Asha,90\nRavi,75\nMeena,88\n")
print(f.readline().rstrip())
for line in f:
    name, mark = line.strip().split(",")
    print(name, int(mark))
Each line still ends with \n, exactly as with a real file.
python
import io

def count_lines(f):
    total = 0
    for line in f:
        if line.strip():
            total += 1
    return total

print(count_lines(io.StringIO("one\ntwo\n\nthree\n")))

out = io.StringIO()
out.write("Total: 250\n")
print(repr(out.getvalue()))
count_lines works with io.StringIO here and with open(...) on your own computer.
Tip: Always pass encoding="utf-8". Without it, Windows may use an older encoding, and Hindi, Tamil or even the rupee sign can turn into junk or raise UnicodeDecodeError.

pathlib, briefly

python
from pathlib import Path
p = Path("reports") / "march.csv"
print(p.as_posix())
print(p.name, p.stem, p.suffix)
Path joins folder and file names with /, the same way on every computer.

On your own computer a Path can also check and read files: p.exists() tells you if the file is there, and p.read_text(encoding="utf-8") reads it in one line. Open a missing file and you get FileNotFoundError, which you can catch with try and except.

Watch the lesson

Working with files · 1/6

Working with files

Files keep your data after the program stops. In this lesson you will read and write text files safely.

Prefer a video by a teacher? Find free videos on “python file handling open read write with statement” on YouTube ↗

In real life: A daily expense log

Pooja adds every expense to a text file with mode "a", one line per expense, so nothing is ever lost. At the end of the month she reads the file back and adds up the amounts. Here io.StringIO stands in for her file, so you can run it in the browser.

python
import io
log = io.StringIO()
for entry in ["Milk,60", "Bus ticket,25", "Vegetables,140"]:
    log.write(entry + "\n")

log.seek(0)            # go back to the start, like opening the file again
total = 0
for line in log:
    item, amount = line.strip().split(",")
    total += int(amount)
print("Spent this month:", total)
Spent this month: 225

Practice (0/3 done)

Task 1 · Code · Python

Write count_lines(text) where text is the whole content of a file. Return how many lines have something in them (ignore empty lines and lines with only spaces). count_lines("a\nb\n\nc\n") returns 3.

Task 2 · Code · Python

Write total_spent(f) where f is an open text file (here an io.StringIO). Each line looks like "Milk,60". Return the total of all the amounts. Skip empty lines.

Task 3 · Code · Python

Write write_report(items, f) where items is a list of (name, qty) pairs and f is a file open for writing (here an io.StringIO). Write one line per item in the form "name: qty", each ending with a new line. Return nothing.

Quick quiz

Question 1

1.Which mode adds new text to the end of a file and keeps the old text?

Question 2

2.You open an existing file with mode "w". What happens to its old content?

Question 3

3.What is the main benefit of with open(...) as f:?

Question 4

4.What is io.StringIO?

Question 5

5.When you loop with for line in f, what is at the end of each line (except maybe the last)?

Read more (free)

Pass the quiz (60% or more) or mark this topic as done when you are ready.

Your progress is saved on this device only.

← Previous: Sorting with key