VMware ESXi and vSphere Cluster Management

How to Read Text Files in Python

Learn how to open, read, iterate through, print, and safely close text files in Python using read(), for loops, and with.

What you need to know first

This lesson assumes you understand Python variables, strings, print(), function and method calls, basic for loops, and filenames and folders. The examples read text files that already exist.

Opening a file for reading

Python's built-in open() function opens a file and returns a file object. A file object is an object that provides access to an open file so your program can read from it or write to it.

To open an existing text file for reading, pass the filename and the read mode, "r":

reader = open('greeting.txt', 'r')

The first argument, 'greeting.txt', is the file path. The second argument, 'r', means read mode. Read mode is intended for retrieving the contents of an existing file; it does not replace or append to the file.

The referenced file must be present at the supplied path. If Python cannot find it, calling open() raises FileNotFoundError.

The file object is not the file text

In this example, reader is a descriptive variable holding the file object:

reader = open('greeting.txt', 'r')

The variable represents an open connection to the file. It does not contain the file's text itself. You retrieve text by calling a method on that object, such as reader.read().

Reading an entire file with read()

The file object's read() method retrieves the remaining file contents as one string. Store the returned string in a separate variable when you want to print it or process it later.

reader = open('greeting.txt', 'r')
contents = reader.read()
print(contents)
reader.close()

Here, reader is the file object and contents is a string containing the text. The call to read() starts at the file's current position and continues to the end.

Reading the whole file is convenient when the complete contents are needed as one value. It is most appropriate for reasonably small text files because the complete string is held in memory at once.

Reading again after read()

A file object keeps a current position, sometimes called a cursor. After read() reaches the end, another call usually returns an empty string:

reader = open('greeting.txt', 'r')
first_read = reader.read()
second_read = reader.read()

print(second_read == '')  # True
reader.close()

If you need to read the contents again, reopen the file or move the position back with reader.seek(0) before reading again.

Reading a file line by line

An open text file can be used directly in a for loop. This is called iteration: processing a sequence one item at a time. Each loop iteration receives one line from the file.

reader = open('tasks.txt', 'r')

for line in reader:
    print(line)

reader.close()

Line strings commonly retain their ending newline character, usually written as \n. Since print() normally adds its own newline, printing a line without changing it can produce extra blank lines.

Use rstrip() when you want to remove trailing whitespace, including the line ending:

reader = open('tasks.txt', 'r')
line_number = 1

for line in reader:
    print(line_number, 'line:', line.rstrip())
    line_number += 1

reader.close()

If you want to preserve the original line ending and avoid adding another one, use end='' with print():

reader = open('tasks.txt', 'r')

for line in reader:
    print(line, end='')

reader.close()

Numbering lines with enumerate()

enumerate() supplies both a counter and the current item. Set start=1 to use human-friendly line numbers instead of starting at zero.

reader = open('tasks.txt', 'r')

for line_number, line in enumerate(reader, start=1):
    print(f'{line_number}: {line.rstrip()}')

reader.close()

Choosing whole-file or line-by-line reading

ApproachResultBest use caseMemory consideration

read() — One string containing the remaining contents — When the full file is needed as one value — The entire result is held in memory.

for line in file — One line per iteration — Incremental processing, records, and potentially large files — Usually uses less memory because lines are processed one at a time.

readline() — One line per method call — When your code needs precise, manual control over individual reads — Only the requested line is returned, but repeated calls require more code.

Choose read() when you need to search, display, or transform the complete text as one string and the file is reasonably small. Choose line iteration when each line is a separate record, when you can process lines independently, or when the file may be large.

Closing a file manually

Call the file object's close() method after all reading is complete:

reader = open('greeting.txt', 'r')
contents = reader.read()
print(contents)
reader.close()

Closing releases operating-system resources associated with the open file and completes file handling cleanly. Do not attempt to read from a file object after calling close(). If more reading is needed, reopen the file.

The preferred pattern: the with statement

The with statement is the modern, preferred way to open files. It automatically closes the file when the indented block finishes, including when an error occurs inside the block.

with open('tasks.txt', 'r') as reader:
    for line_number, line in enumerate(reader, start=1):
        print(f'{line_number}: {line.rstrip()}')

The name after as, such as reader, refers to the file object inside the block. Once execution leaves the block, Python closes the file automatically. This gives you the same cleanup goal as manually calling close(), while reducing the chance of forgetting it.

You can also read a complete small file with this pattern:

with open('greeting.txt', 'r') as reader:
    contents = reader.read()

print(contents)

The variable contents remains available after the block because it stores a separate string. The file object itself has been closed.

File paths and common read failures

Relative paths

A relative path is interpreted from the program's current working directory. If your script opens 'greeting.txt', Python looks for that file in the current working directory, which may not be the same folder as the script file.

with open('data/greeting.txt', 'r') as reader:
    print(reader.read())

This example looks for a data folder inside the current working directory. Check the exact filename, capitalization, extension, and folder structure.

Absolute paths

An absolute path identifies a file from a filesystem root, so it does not depend on the current working directory. Use one when the file is elsewhere, while remembering that path syntax differs between operating systems.

FileNotFoundError

FileNotFoundError is raised when Python cannot locate the requested file. Common causes include a misspelled filename, a missing or incorrect extension, a different working directory, incorrect path separators, or a path pointing to the wrong folder.

Verify the exact path and then provide the correct relative or absolute path. You can also handle the failure gracefully:

try:
    with open('settings.txt', 'r') as reader:
        print(reader.read())
except FileNotFoundError:
    print('The requested file was not found.')

Permission-related failures

A correct path does not guarantee access. The user or process may lack permission to read the file, or the environment may impose another restriction. Check the file permissions and run the program in an environment with appropriate access.

Troubleshooting reading code

Extra blank lines appear

The line already contains a newline character, and print() adds another one. Use line.rstrip() before printing, or use print(line, end='') when preserving the original line endings.

read() returns an empty string

The file may be empty, or the file cursor may already be at the end because an earlier read() consumed the contents. Check the file and either reopen it or call reader.seek(0) before reading again.

An operation fails after close()

This happens when code attempts to use a closed file object. Perform all reads before closing, or reopen the file in a new with block.

Beginner reference: opening modes

ModePurposeFile must already existCan modify contents

r — Read an existing file — Yes — No

w — Write new contents, replacing existing contents — No — Yes; existing contents are replaced

a — Append new contents to the end — No — Yes; existing contents are preserved

This lesson uses r because the goal is to retrieve text from an existing file. Writing and appending use different modes and require care because they can change the file.

Complete example

The following program uses the preferred automatic-closing pattern, numbers each line, and removes line endings only for display:

with open('tasks.txt', 'r') as reader:
    for line_number, line in enumerate(reader, start=1):
        print(f'{line_number}: {line.rstrip()}')
  1. Python opens tasks.txt in read mode.
  2. reader stores the file object.
  3. The for loop reads one line during each iteration.
  4. enumerate() supplies a line number starting at one.
  5. rstrip() removes the ending newline for cleaner output.
  6. After the block finishes, the with statement closes the file.

Key points

  • Use open(filename, 'r') to open an existing text file for reading.
  • The result of open() is a file object, not the file's text.
  • Use read() to retrieve the remaining contents as one string.
  • Iterate directly over the file object to process one line at a time.
  • Lines often retain a \n newline character.
  • Call close() after manual file handling, or preferably use with for automatic cleanup.
  • Use relative paths from the current working directory or provide an absolute path.
  • Expect FileNotFoundError for incorrect names or locations, and check permissions when access is denied.

For the related lesson, see reading a file in Python.