Files and Exceptions

While a program is running, its data is in memory. When the program ends, or the computer shuts down, data in memory disappears. To store data permanently, you have to put it in a file. Files are usually stored on a hard drive, portable drive, or CD-ROM.

When there are a large number of files, they are often organized into directories (also called "folders"). Each file is identified by a unique name, or a combination of a file name and a directory name.

By reading and writing files, programs can exchange information with each other and generate printable formats like PDF.

Working with files is a lot like working with books. To use a book, you have to open it. When you're done, you have to close it. While the book is open, you can either write in it or read from it. In either case, you know where you are in the book. Most of the time, you read the whole book in its natural order, but you can also skip around.

All of this applies to files as well. To open a file, you specify its name and indicate whether you want to read or write.

Opening a file creates a file object. In this example, the variable file refers to the new file object.


with open('my_file.txt', 'r') as file:

print(file)

<_io.TextIOWrapper name='adverbs.txt' mode='r' encoding='cp1252'>


The open function takes two arguments. The first is the name of the file, and the second is the mode. When we print the file object, we see the name of the file, the mode, and the encoding of the object.

Mode "w" means that we are opening the file for writing.


with open('my_file.txt', 'w') as file:

file.write('This is a line of my new file.')


If there is no file named my_file.txt, it will be created. If there already is one, it will be replaced by the file we are writing.

To put data in the file we invoke the write method on the file object:


with open('my_file.txt', 'w') as file:

file.write('This is a line of my new file\n')

file.write('This is another line of my new file\n')

file.write('This is the last line of my new file\n')


Closing the file tells the system that we are done writing and makes the file available for reading. Closing the file consists of eliminating the indentation of the

with open()as file_var:

body

Now we can open the file again, this time for reading, and read the contents into a string. This time, the mode argument is "r" for reading:


with open('my_file.txt', 'r') as file:


If we try to open a file that doesn't exist, we get an error:


with open('myFile.txt', 'r') as file:

print(file)

FileNotFoundError: [Errno 2] No such file or directory: 'myFile.txt'


Not surprisingly, the read method reads data from the file. With no arguments, it reads the entire contents of the file:


with open('my_file.txt', 'r') as file:

text = file.read()

print(text)


This is a line of my new file

This is another line of my new file

This is the last line of my new file


Noticed that each line of text was placed on a separate line because of the new line character used in the string placed in the write() function. Remove the '\n' in the your write() functions and see how Python handles this.

Also notice the print() is not indented. This forces python to close the open file. End the indentation as soon as you have the information required from the file.

read() can also take an argument that indicates how many characters to read:


with open('my_file.txt', 'r') as file:

text = file.read(10)

print(text)


This is a


If not enough characters are left in the file, read() returns the remaining characters. When we get to the end of the file, read returns the empty string:

The following function copies a file, reading and writing up to fifty characters at a time. The first argument is the name of the original file; the second is the name of the new file:


def copy_file(old_file, new_file, length):

with open(old_file, 'r') as first, \

open(new_file, 'w')as second:

text = first.read(length)

second.write(text)


Here I've create a function that copies a portion (of length length) of a file to another file. The with open()... statement can open as many files as you would like. Make sure to use different variable names (first and second above) for each file object you create.

Sometimes you'll come across files that have text formatted in different ways. If this is the case you can reformat the text to be more friendly for your use.


with open('my_file.txt', 'r', encoding='utf-8-sig') as file:

text = file.read()


Adding the encoding='utf-8-sig' parameter should reformat the text.


11.1 Text files

A text file is a file that contains printable characters and whitespace, organized into lines separated by newline characters. Since Python is specifically designed to process text files, it provides methods that make the job easy.

The readline() method reads all the characters up to and including the next newline character:


with open('my_file.txt', 'r') as file:

text_line = file.readline()

print(text_line)


This is a line of my new file


readlines() returns all of the remaining lines as a list of strings:


with open('my_file.txt', 'r') as file:

text_lines = file.readlines()

print(text_lines)


['This is a line of my new file\n', 'This is another line of my new file\n', 'This is the last line of my new file\n']


In this case, the output is in list format, which means that the strings appear with quotation marks and the newline character appears as the escape sequence.

The following is an example of a line-processing script:


with open('my_file.txt', 'r') as file:

text = file.readline()

while text:

print(text)

text = file.readline()


This is an example of how to process a file line by line. Each to readline() is called it will read the next line. The readline() call in the while loop will read the file, line by line, until there are no lines remaining.

At the end of the file, readline() returns the empty string and readline()returns the empty list. Thus, if text is the empty string, this returns a value of False, and the loop exits.


11.2 Writing variables

The argument of write has to be a string, so if we want to put other values in a file, we have to convert them to strings first. The easiest way to do that is with the str function:

>>> x = 52

>>> file.write(str(x))

An alternative is to use the f-string. The f-string is a string which contains one or more format codes (fields to be replaced) embedded in constant text. The "fields to be replaced" are surrounded by curly braces {}. The curly braces and the "code" or the value of the variable inside will be substituted with a formatted value according to the rules which we will specify soon. Anything else, which is not contained in curly braces will be literally printed, i.e. without any changes.