Reading and writing files

INPUT · Slides

Have it closed for you

01 / 07

Forgetting happens however careful you are

The last exercise of the previous lesson took four close calls. More files, more calls. However careful you are, one day you will forget.

Worse is when an error happens before the close. The program stops there, so it never reaches that line.

What you want is not "try harder to remember" but a shape where there is nothing to forget. That is with.

02 / 07

The shape of with

Write with open("memo.txt") as f:, end the line with a :, and indent from the next line. The same familiar shape as if and for.

As you come back out of the indented block, Python closes it automatically. There is no longer anywhere to put a close.

with open("memo.txt", "w") as f:    f.write("morning")with open("memo.txt") as f:    print(f.read())

Result

morning

03 / 07

Check that it really is closed

A file carries a closed label that tells you whether it is shut. Have a look at it after the block.

It says True. The close you never wrote has definitely run.

with open("memo.txt", "w") as f:    f.write("morning")print(f.closed)

Result

True

04 / 07

After as comes an ordinary variable name

as f means "call the file you just opened f". Nothing says it has to be f.

Give it whatever reads well. That said, f is so common in Python that you want to see an f and think "file" when you read other people's code.

with open("memo.txt", "w") as text_file:    text_file.write("noon")with open("memo.txt") as text_file:    print(text_file.read())

Result

noon

05 / 07

It closes even when something goes wrong

Here is the best part of with. Even if an error happens inside the block, it is closed on the way out.

The example below reads the file and then raises an error on purpose with 1 / 0. Catch it with except, look at closed, and you get True. Had you written the close by hand, this file would have been left open.

with open("memo.txt", "w") as f:    f.write("morning")try:    with open("memo.txt") as f:        print(f.read())        print(1 / 0)except ZeroDivisionError:    print("division went wrong")print(f.closed)

Result

morning
division went wrong
True

06 / 07

Keep the block short

The file stays open the whole time you are inside the with block. So do only the reading and writing in there and carry on outside. That is the tidy way to write it.

Put what you read into a variable and it is still yours after the block, because closing a file does not empty the string you read out of it.

with open("memo.txt", "w") as f:    f.write("apple")with open("memo.txt") as f:    text = f.read()print(f"contents: {text}")

Result

contents: apple

07 / 07

Summary

with is this sort of tool.

  • write with open(...) as f: and indent
  • Python closes it as you leave the block
  • it closes even if an error happens partway

From here on you can take it that you open a file with with. In real code you very rarely see a bare open.

Next we go deeper into the reading. Instead of the whole thing at once, you will handle it a line at a time.