LEARN PYTHON | Text Files And Context Managers

Lesson objective

Read, write and append UTF-8 text files, explain file position and use a context manager to close a file reliably.

Learn

05.1 | TEXT FILES AND CONTEXT MANAGERS

01 | MEMORY ENDS, FILES REMAIN

Your quiz scoreboard lived in a list while Python was running. When the process ended, that in-memory list disappeared. A file stores bytes outside the process so a later run can read them. This is persistence.

A text file is a useful first step: save a short message, reopen it and display it. Saving a Python source file and saving a program’s data are separate operations. An editor stores instructions; your running program can store the information it produces.

Work in a new practice folder and use the filenames shown. The examples deliberately create or change those practice files. Before choosing a write mode for an existing file, decide whether replacing its current contents is intended.

02 | OPEN CONNECTS YOUR PROGRAM TO A FILE

open() returns a file object. It provides methods such as read() and write(), tracks a current position and manages a connection to the operating system. The filename identifies the resource; the file object is the program’s working handle.

The mode tells Python what operation you want. "r" reads an existing file; "w" writes and truncates an existing file as soon as opening succeeds; "a" writes at the end; "x" creates a new file and fails if it already exists. "w", "a" and "x" can create a file when the parent folder exists.

A relative filename such as notes.txt is interpreted relative to the current working directory. That is not always the folder containing your script. The pathlib lesson will make locations explicit.

ModeMain purposeExisting fileMissing file
rReadPreservedFileNotFoundError
wWrite from beginningTruncated on openCreated
aAppendNew writes go to endCreated
xExclusive creationFileExistsErrorCreated

03 | WITH MANAGES THE LIFETIME

A context manager manages setup and cleanup around a block. With a file, the with statement opens the resource and closes it when the block finishes, including when an exception leaves that block. The name after as is bound to the file object.

The indented body is the period during which this file is open. A file.close() call after an ordinary block can be skipped when an earlier operation fails; with gives the cleanup a reliable structure. Closing also flushes Python’s buffered writes, but it is not a guarantee against every disk failure or power loss.

The file variable still exists after the block, but its file object is closed. Trying another read or write through that closed object raises ValueError. A new operation needs another open.

with open("notes.txt", "w", encoding="utf-8") as file:
    file.write("One useful idea\n")

print("Closed:", file.closed)

EXPECTED OUTPUT

Closed: True

04 | WRITE TEXT AND ADD LINE ENDINGS

write() accepts text in text mode. It does not add a line ending automatically. The escape sequence \n represents a newline character inside a Python string. Writing two strings without a separator joins their characters in the file.

The return value from write() is the number of characters accepted by the text stream, not necessarily the number of encoded bytes on disk. Text such as café can use more bytes than characters in UTF-8.

Use encoding="utf-8" explicitly so your program follows a predictable text encoding rather than depending on a platform default. Encoding converts characters to bytes; decoding converts stored bytes back to characters.

with open("notes.txt", "w", encoding="utf-8") as file:
    written = file.write("Learn one idea\n")
    file.write("Test it yourself\n")

print("First write characters:", written)

EXPECTED OUTPUT

First write characters: 15

05 | READ ALL TEXT OR ONE LINE AT A TIME

read() returns the remaining text from the current file position. For a small file, that is convenient. Iterating over the file yields lines without first loading the entire file into one string, which can suit larger files.

A line read from a text file usually includes its terminating newline. print(line) then adds another newline, causing apparent blank gaps. Use print(line, end="") to display the existing line ending without adding another.

readline() returns one line or an empty string at end of file. A blank line containing a newline is not the same as the end-of-file empty string. These differences matter when processing records.

with open("notes.txt", "w", encoding="utf-8") as file:
    file.write("Learn\nTest\n")

with open("notes.txt", "r", encoding="utf-8") as file:
    for line in file:
        print(line, end="")

EXPECTED OUTPUT

Learn
Test

06 | A READ ADVANCES THE POSITION

Reading consumes characters from the stream’s current position. After read() reaches the end, another read() returns empty text. It does not restart automatically. Reopen the file when you want a simple fresh read.

seek(0) moves to the beginning. In text mode, do not treat every seek offset as a freely chosen byte or character index; encodings and newline translation make arbitrary positioning more complicated. This lesson uses only the simple reset to zero.

Do not mistake an empty second read for an empty file. Ask where the stream position is and whether another operation has already consumed its contents.

with open("notes.txt", "w", encoding="utf-8") as file:
    file.write("ROBOT")
with open("notes.txt", "r", encoding="utf-8") as file:
    print(repr(file.read()))
    print(repr(file.read()))
    file.seek(0)
    print(repr(file.read()))

EXPECTED OUTPUT

'ROBOT'
''
'ROBOT'

07 | APPEND WITHOUT REPLACING EARLIER NOTES

Append mode sends new writes to the end rather than clearing earlier text. It suits a simple log or a growing list of lines. It does not inspect whether the current last line already ends with a newline.

If a file ends with hello and you append world, the result is helloworld. Design a consistent record separator and write it yourself. Append is not the same as editing an arbitrary existing record.

The example first deliberately writes a known practice file, then appends one more line. In an application, repeatedly running the append operation can create repeated entries; decide whether that is intended.

with open("notes.txt", "w", encoding="utf-8") as file:
    file.write("First note\n")
with open("notes.txt", "a", encoding="utf-8") as file:
    file.write("Second note\n")
with open("notes.txt", "r", encoding="utf-8") as file:
    print(file.read(), end="")

EXPECTED OUTPUT

First note
Second note

08 | TRIM ONLY WHAT YOU MEAN TO TRIM

strip() removes leading and trailing whitespace, not just a newline. That is useful for a menu response but can erase meaningful spaces from a text record. For a line ending, line.rstrip("\n") removes trailing newline characters while preserving surrounding spaces.

Ordinary text reading uses universal newline handling, so common line endings are normally presented as \n. If a format has stricter requirements, design its parsing explicitly. Do not use broad trimming simply because output looks untidy.

A text file stores characters, not automatic Python types. Reading "12" gives text until you choose a conversion and validate it. The next lesson introduces structured formats with clearer record boundaries.

09 | COMPARE FILE MODES IN A SAFE MODEL

This browser model begins with a pretend file containing First note followed by a newline. It shows what different modes do without accessing your computer’s files. Reset restores the initial content.

10 | HANDLE FAILURE WITHOUT HIDING IT

Opening can fail because a path is missing, permissions do not allow access or the storage is unavailable. A context manager closes an opened file; it does not make every operation succeed or suppress every exception.

In the validation lesson, you will catch specific failures where the application can give useful feedback or recover. A missing optional data file might mean a new tracker. A damaged existing save file must not automatically be treated as an empty tracker and overwritten.

Keep the distinction between data in memory, a write accepted by Python, a closed file and a later successful reload. Testing persistence means ending or resetting the in-memory state and reading the saved data again.

PUT YOUR SKILLS TO WORK

Use the Section 5 challenges to practise these ideas independently. Work in your Python editor, predict results and keep a short test record.

Section 5 challenges Python course navigation

MATCH THE PYTHON TERM TO ITS MEANING

Terminology

Terminology

Persistence

Keeping data beyond the current process or session.

File object

An object providing operations on an opened file stream.

Mode

The requested way to open and use a file.

Read mode

r: read an existing file without truncating it.

Write mode

w: write, creating or truncating a file.

Append mode

a: direct new writes to the end of a file.

Exclusive creation

x: create a file only if it does not already exist.

Truncation

Clearing existing file contents when an appropriate write open succeeds.

Context manager

An object managing entry and exit around a with block.

with statement

A statement using a context manager for structured setup and cleanup.

Encoding

A rule for converting text characters into bytes.

UTF-8

A widely used Unicode text encoding.

Newline

A character or sequence marking a line ending.

File position

The stream location from which the next read occurs.

End of file

The point at which no more input remains in a stream.

Buffer

Temporary storage used before data is transferred onward.

Relative path

A location interpreted from a base such as the working directory.

FileNotFoundError

An exception signalling that a requested path cannot be found.

Questions

Questions

CHECK YOUR UNDERSTANDING

Select all correct choices. Each exact set earns one point.

1. Which mode truncates an existing file when opening succeeds?
2. What does with provide for an opened file?
3. What does write("Hello") add automatically?
4. After read() consumes the entire file, what does another read() normally return?
5. Which statements about text and encoding are correct?
6. Which mode refuses to create over an existing file?
7. Why can print(line) produce apparent blank lines during file iteration?
8. Which practice preserves meaningful outer spaces when removing newlines?

EXPLAIN AND COMPARE

Write your answers before revealing each sample.

1. Explain persistence using the quiz scoreboard.

2. Compare w, a and x.

3. Explain what the file context manager does.

4. Explain why two reads can give different results.

5. Describe newline handling when printing lines.

6. Explain characters versus bytes.

7. Suggest how to trim a stored line.

8. Design a persistence check.

CODE IT | YOUR INDEPENDENT CHALLENGE

Create a UTF-8 note file, append one line and reopen it. Explain the mode choice, newline and context lifetime.

Work in your Python editor. Keep a working version, explain one design choice and record at least two tests. Use the Learn tab for worked examples before comparing your result.

Flashcards

Flashcards

Click to flip. Select the ideas you need to revisit.

0 cards selected for revision.

    Selections are kept while this page is open.

    Workbook

    Workbook

    COMING SOON

    The workbook for Text Files And Context Managers is coming soon. Complete the matching task and written questions in your exercise book.