Книга: Practical Programming, Fourth Edition
Назад: Opening a File
Дальше: Files over the Internet

Techniques for Reading Files

As mentioned at the beginning of the chapter, Python provides several techniques for reading files. You’ll learn about them in this section.

All of these techniques work starting at the current position. That allows you to combine the techniques as needed.

The Read Technique

Use this technique when you want to read the contents of a file into a single string, or when you want to specify exactly how many characters to read. This technique was introduced in ; here is the same example:

 with​ open(​'file_example.txt'​, ​'r'​) ​as​ infile:
  contents = infile.read()
 
 print​(contents)

When called with no arguments, the read method reads everything from the current position to the end of the file and advances the current position to the end of the file. When called with one integer argument, it reads that many characters and advances the current position after the characters that were just read. Here is a version of the same program in a file called file_reader_with_10.py; it reads ten characters and then the rest of the file:

 with​ open(​'file_example.txt'​, ​'r'​) ​as​ infile:
  first_ten_chars = infile.read(10)
  the_rest = infile.read()
 
 print​(f​'The first 10 characters: {first_ten_chars}'​)
 print​(f​'The rest of the file: {the_rest}'​)

Method call example_file.read(10) updates the current position, so the next call, example_file.read, reads everything from character 11 to the end of the file.

The Readlines Technique

File contents are commonly stored in lists of strings

Use this technique when you want to get a Python list of strings containing the individual lines from a file. Function readlines works much like function read, except that it splits up the lines into a list of strings. As with read, the current position is moved to the end of the file.

Reading at the End of a File

icon indicating an aside

When the current file position is at the end of the file, methods read and readline return an empty string and readlines returns an empty list. To read the contents of a file a second time, you’ll need to close and reopen the file.

This example reads the contents of a file into a list of strings and then prints that list:

 with​ open(​'file_example.txt'​, ​'r'​) ​as​ infile:
  lines = infile.readlines()
 
 print​(lines)

Here is the output:

 ['First line of text.\n', 'Second line of text.\n', 'Third line of text.\n']

Take a close look at that list: each line ends in a \n character. Python does not remove any characters from what is read; it only splits them into separate strings.

The last line of a file may or may not end with a newline character, as you learned in .

Assume file planets.txt contains the following text:

 Mercury
 Venus
 Earth
 Mars

This example prints the lines in planets.txt backward, from the last line to the first (use the built-in function reversed, which returns the items in the list in reverse order):

 >>>​​ ​​with​​ ​​open(​​'planets.txt'​​,​​ ​​'r'​​)​​ ​​as​​ ​​planets_file:
 ...​​ ​​planets​​ ​​=​​ ​​planets_file.readlines()
 ...
 >>>​​ ​​planets
 ['Mercury\n', 'Venus\n', 'Earth\n', 'Mars\n']
 >>>​​ ​​for​​ ​​planet​​ ​​in​​ ​​reversed(planets):
 ...​​ ​​print(planet.strip())
 ...
 Mars
 Earth
 Venus
 Mercury

You can use the Readlines technique to read the file, sort the lines, and print the planets alphabetically. Here, the built-in function sorted is used, which returns the items in the list in alphabetical order:

 >>>​​ ​​with​​ ​​open(​​'planets.txt'​​,​​ ​​'r'​​)​​ ​​as​​ ​​planets_file:
 ...​​ ​​planets​​ ​​=​​ ​​planets_file.readlines()
 ...
 >>>​​ ​​planets
 ['Mercury\n', 'Venus\n', 'Earth\n', 'Mars\n']
 >>>​​ ​​for​​ ​​planet​​ ​​in​​ ​​sorted(planets):
 ...​​ ​​print(planet.strip())
 ...
 Earth
 Mars
 Mercury
 Venus

The “For Line in File” Technique

Use this technique when you want to do the same thing to every line from the current position to the end of a file. On each iteration, the current position is set at the beginning of the next line.

This code opens the file planets.txt and prints the length of each line in that file:

 >>>​​ ​​with​​ ​​open(​​'planets.txt'​​,​​ ​​'r'​​)​​ ​​as​​ ​​data_file:
 ...​​ ​​for​​ ​​line​​ ​​in​​ ​​data_file:
 ...​​ ​​print(len(line))
 ...
 8
 6
 6
 5

Take a close look at the last line of output. There are only four characters in the word Mars, but the program reports that the line is five characters long. The reason for this is the same as for the readlines function: each line you read from the file has a newline character at the end. You can remove it using the string method str.strip, which returns a copy of a string with leading and trailing whitespace characters (spaces, tabs, and newlines) stripped away:

 >>>​​ ​​with​​ ​​open(​​'planets.txt'​​,​​ ​​'r'​​)​​ ​​as​​ ​​data_file:
 ...​​ ​​for​​ ​​line​​ ​​in​​ ​​data_file:
 ...​​ ​​print(len(line.strip()))
 ...
 7
 5
 5
 4

The Readline Technique

This technique reads one line at a time, unlike the Readlines technique. Use this technique when you want to read only part of a file.

For example, you may treat lines differently depending on context; you may wish to process a file that has a header section followed by a series of records, either one record per line or with multiline records.

The following data, taken from the , describes the number of colored fox fur pelts produced in Hopedale, Labrador, from 1834 to 1842. (The full data set has values for the years 1834--1925.)

 Coloured fox fur production, HOPEDALE, Labrador, 1834-1842
 #Source: C. Elton (1942) "Voles, Mice and Lemmings", Oxford Univ. Press
 #Table 17, p.265--266
  22
  29
  2
  16
  12
  35
  8
  83
  166

The first line of a Time Series Data Library (TSDL) file contains a description of the data. The following two lines contain comments about the data, each of which begins with a # character. Each piece of actual data appears on a single line.

Let’s use the Readline technique to skip the header, and then use the “For Line in File” technique to process the data in the file, counting how many fox fur pelts were produced.

 with​ open(​'hopedale.txt'​, ​'r'​) ​as​ hopedale_file:
 
 # Read and skip the description line.
  hopedale_file.readline()
 
 # Keep reading and skipping comment lines until we read the first piece
 # of data.
  data = hopedale_file.readline()
 while​ data.startswith(​'#'​):
  data = hopedale_file.readline()
 
 # Now we have the first piece of data. Accumulate the total number of
 # pelts.
  total_pelts = int(data)
 
 # Read the rest of the data.
 for​ data ​in​ hopedale_file:
  total_pelts += int(data)
 
 print​(f​'Total number of pelts: {total_pelts}'​)

And here is the output:

 Total number of pelts: 373

Each call to the readline method sets the current position to the beginning of the next line.

Sometimes the leading whitespace is important and you’ll want to preserve it. In the Hopedale data, for example, the integers are right-justified to make them line up nicely. To preserve this alignment, you can use rstrip to remove the trailing newline. Here is a program that prints the data from that file, preserving the leading whitespace:

 with​ open(​'hopedale.txt'​, ​'r'​) ​as​ hopedale_file:
 
 # Read and skip the description line.
  hopedale_file.readline()
 
 # Keep reading and skipping comment lines until we read the first piece
 # of data.
  data = hopedale_file.readline()
 while​ data.startswith(​'#'​):
  data = hopedale_file.readline()
 
 # Now we have the first piece of data.
 print​(data.rstrip())
 
 # Read the rest of the data.
 for​ data ​in​ hopedale_file:
 print​(data.rstrip())

And here is the output:

 ​ 22
 ​ 29
 ​ 2
 ​ 16
 ​ 12
 ​ 35
 ​ 8
 ​ 83
 ​ 166

It’s Unsafe to read

icon indicating an aside

Calling read or readlines with no arguments is fine for small files, but risky for large or unknown-sized files. They may cause high memory usage, performance issues, and even crashes due to out-of-memory errors. Prefer line-by-line iteration or controlled chunk reading for safety and scalability.

Назад: Opening a File
Дальше: Files over the Internet