15  Working with files

This chapter covers the bare necessities of making your program read data from a file on your computer and how to create a file to write results.

Writing files

To interact with a file on your hard disk, you need to know its name and whether you want to write to it or read from it. Then, you can use the built-in function open to create a file object that lets you read or write to that file. The open function takes two arguments: The first is a string, which gives the file’s name. The second argument is also a string and should be 'w' for “write” if you want to write to the file or 'r' for “read” if you are going to read from the file. To keep things simple, we will assume that the file you want to open is always in the same folder (directory) as the Python script that calls the open function.

Exercise 15-1

Try to write the code below and run it:

f = open('workfile.txt', 'w')
f.write("First line\n")
f.write("Second line\n")
f.close()

Now open the workfile.txt in VScode and see what is in it now. It should contain:

First line
Second line

Let’s break down what happened:

  1. You used the open built-in function to open a file called “workfile.txt” in writing mode using the 'w' as the second argument.
  2. You then wrote the string "First line\n" to the file using the write method of the file object.
  3. You wrote another string "Second line\n" to the file using the write method of the file object.
  4. You closed the file using the close method of the file object.

Note that if you open a file for writing, a file with that name is created. If a file of that name already exists, it is overwritten.

Exercise 15-2

Close workfile.txt in VScode again and change your program above to this (removing the \n characters):

f = open('workfile.txt', 'w')
f.write("First line")
f.write("Second line")
f.close()

What do you think the content of workfile.txt is now? Decide before you open workfile.txt in VScode again and have a look. What do you think the \n character represents?

Exercise 15-3

Close workfile.txt in VScode and change your program above to this:

f = open('workfile.txt', 'w')
f.write("First line\nSecond line\n")
f.close()

Can you see how that is equivalent to what you did before? Open workfile.txt in VScode again and have a look.

Exercise 15-4

You can also make print write to a file instead of the terminal. That way, your output will end up in the file instead of the terminal. To make print write to a file, you need to use print’s file keyword argument to tell print which file to write to. The argument must be an object that represents the file you want to write to (file=f below). Try to write the code below and run it:

f = open('workfile.txt', 'w')
print("First line", file=f)
print("Second line, file=f")
f.close()

Compare the code to that in Section 15.0.0.1. Notice how the strings we print end with a newline character \n. This is because the default behavior for print is to add a new line to the end of what it prints—just like when you print to the terminal.

Reading files

When you want to read a from an existing file, you give the open function the name of that file and specify 'r' for reading as a second argument. If the file you name does not exist, Python will tell you it does not exist (it is nice like that). Before you head into the rest of this section, make sure you redo Section 15.0.0.1 so the content of workfile.txt is:

First line
Second line

Exercise 15-5

f = open('workfile.txt', 'r')
file_content = f.read()
print(file_content)
f.close()

Let’s break down what happened:

  1. You used the open built-in function to open a file called workfile.txt in reading mode using the 'r' as the second argument.
  2. You then read the file’s content using the read method, which returns the contents as a string.
  3. You printed the string.
  4. You closed the file using the close method of the file object.

Exercise 15-6

Try to read from the file after you close it:

f = open('workfile', 'r')
f.close()
file_content = f.read()

Do you get an error? Which one? Do you understand why?

Exercise 15-7

You can use the readline method to read one line at a time. What do you think happens if you run this code:

f = open('workfile.txt', 'r')
line = f.readline()
print(line)
line = f.readline()
print(line)
line = f.readline()
print(line)

Once you decide, try it out. What is printed in the last print statement? The thing is, the file object keeps track of how much of the file it has read. Once it ends, you can read as much as you like- nothing is left. If you want to start reading from the top of the file, you can close it and open it again. Try to insert the following two statements at various places in the code above and see what happens.

f.close()
f = open('workfile.txt', 'r')

Exercise 15-8

Look at the code below and figure out for yourself what it does:

input_file = open('workfile.txt', 'r')
output_file = open('results.txt', 'w')

for line in input_file:
    line = line.upper()
    output_file.write(line)

Then, run it and open results.txt in VScode and see what it produced.

Were you surprised that the file object can be an iterator in a for-loop? Just like stings can iterate over characters, lists can iterate over values, dictionaries can iterate over keys, and file objects can iterate over the lines in the file.

Try to modify your code to use the print function instead of the write method (see Section 15.0.0.4).

General exercises

Exercise 15-9

Write a function read_file that takes the name of a file as an argument. The function should read the content and return it. Like:

content_of_file = read_file('some_file.txt')

Exercise 15-10

Write a function that takes the name of two files as arguments. The file should read the content of the first file and write it to the second file.

copy_file('some_file.txt', 'other_file.txt')