A Wandering Mind · Computer Science
PYTHON GUIDE

Learn · Run · Break · Fix

A learning series from A Wandering Mind

Eighteen interlinked lessons on strings, lists, files, exceptions, and dictionaries—with original explanations, runnable examples, real output, and supporting CPSC 1301K lectures.

course.py
>>> guide = {
...   "lessons": 18,
...   "modules": 5,
...   "python": "3.10+"
... }
>>> guide["goal"] = "understand it"
Module 3 · Files · Lesson 11 of 18

How File I/O Works, and Opening a File in Python

Variables and lists disappear when a program ends unless their data is stored somewhere persistent. File input/output—usually shortened to file I/O—lets Python connect a running program to files on disk. This lesson explains paths, file modes, the object returned by open(), and the important differences between opening a file for reading, writing, appending, or exclusive creation.

Prerequisite: Complete Looping Over Lists and Nested Lists. The file module will reuse strings, lists, loops, and exception messages from earlier lessons.

File I/O connects memory to persistent storage

During a program run, Python keeps variables and objects in memory. That is perfect for calculations, temporary state, and data your program is actively using. But memory is not the same thing as a saved file. If you need information to remain available after the program stops, or you need to work with information created by another program, a file is one common bridge.

The term input means data entering your program, such as text read from a file. Output means data leaving the program, such as text written to a file. Before either operation can happen, Python needs to open the file and create a file object representing that connection.

open() returns a file object

The built-in open() function accepts a path and a mode. For a normal text file that already exists, open("notes.txt", "r") asks Python to open notes.txt for reading. If successful, the result is a file object. That object carries information about the open connection and provides the methods later lessons will use to read or write data.

For text files, explicitly supplying encoding="utf-8" is a good modern habit when you control the file format. It makes the intended character encoding clear instead of relying on a platform-dependent default.

Example 1 · Open an existing text fileVerified
file = open("notes.txt", "r", encoding="utf-8")
print(file.name)
print(file.mode)
file.close()
notes.txt
r

The name attribute records the path used to open the file, while mode reports the active mode. The final close() is included so the example does not leave the resource open; the next lesson explains proper closing and the preferred with pattern in detail.

Opening is not the same as reading. open() creates the connection and returns a file object. Methods such as read() and iteration actually retrieve file contents, which is why they are saved for later lessons.

A path tells Python which file you mean

A simple filename such as "notes.txt" is a relative path. Python resolves relative paths from the program’s current working directory, which is not always identical to the folder containing the script. Development tools, notebooks, servers, and command-line launches can all affect the working directory.

Paths can also include folders. On a project where a data directory contains scores.txt, the relative path can be written as "data/scores.txt" on modern Python code using forward slashes in this style.

Example 2 · Open a file inside a subfolderVerified
file = open("data/scores.txt", "r", encoding="utf-8")
print(file.name)
print(file.mode)
file.close()
data/scores.txt
r

If this path fails, the first debugging question should be whether that location exists relative to the current working directory. A valid filename in the wrong directory is still the wrong path from Python’s perspective.

File modes tell Python what kind of access you want

The mode is not decoration. It changes what Python is allowed to do and, in some cases, what happens to the file immediately. The four modes beginners should recognize first are "r", "w", "a", and "x".

Read"r"

Opens an existing file for reading. Fails if the file does not exist.

Write"w"

Opens for writing, creating the file if needed. An existing file is truncated.

Append"a"

Opens for writing at the end and creates the file if it does not exist.

Exclusive create"x"

Creates a new file but fails if that path already exists.

The most dangerous beginner mistake is casually testing "w" on a file you care about. Opening an existing file in write mode truncates it—effectively reducing its contents to zero length—before you later write new data. That behavior is useful when intentional and destructive when accidental.

Exclusive creation protects against accidental overwrite

The "x" mode is useful when the program should create a brand-new file and refuse to continue if that filename is already taken. It turns “do not overwrite an existing file” into a rule enforced by Python rather than a promise you have to remember manually.

Example 3 · Create only if the file is newVerified
file = open("new-report.txt", "x", encoding="utf-8")
print(file.name)
print(file.mode)
file.close()
new-report.txt
x

This succeeds only when new-report.txt does not already exist. Running the same code a second time without removing or renaming the file raises FileExistsError. That failure is deliberate protection, not a bug in the mode.

Text mode and binary mode are different kinds of data

Python normally opens files in text mode, represented by "t". The mode "r" therefore behaves like "rt". Text mode works with Python strings and character encodings. Binary mode uses "b" and works with bytes, which is appropriate for data such as images, compressed files, and many other non-text formats.

Example 4 · Compare text and binary modesVerified
text_file = open("notes.txt", "rt", encoding="utf-8")
binary_file = open("sample.bin", "rb")
print(text_file.mode)
print(binary_file.mode)
text_file.close()
binary_file.close()
rt
rb

Binary mode does not accept a text encoding argument because bytes are not being decoded into strings. This course will concentrate on text files, but recognizing "rb" and "wb" will help you understand code that works with binary data later.

Common mistakes when opening files

File-opening failures often contain useful operating-system information. The following tracebacks were produced by real Python executions.

Mistake 1 · Reading a path that does not exist
file = open("missing.txt", "r")
Traceback (most recent call last):
  File "/tmp/awm_lesson11/work/mistake1.py", line 1, in <module>
    file = open("missing.txt", "r")
FileNotFoundError: [Errno 2] No such file or directory: 'missing.txt'

Read mode expects the file to exist. Check the spelling, working directory, folder path, and whether the file has actually been created.

Mistake 2 · Opening a directory as though it were a file
file = open("data", "r")
Traceback (most recent call last):
  File "/tmp/awm_lesson11/work/mistake2.py", line 1, in <module>
    file = open("data", "r")
IsADirectoryError: [Errno 21] Is a directory: 'data'

The path exists, but it identifies a directory rather than a regular file. A valid path must point to the type of resource the operation expects.

Mistake 3 · Writing the word read instead of the mode r
file = open("notes.txt", "read")
Traceback (most recent call last):
  File "/tmp/awm_lesson11/work/mistake3.py", line 1, in <module>
    file = open("notes.txt", "read")
ValueError: invalid mode: 'read'

Modes use specific short strings. Python does not translate descriptive words such as "read" into "r".

Mistake 4 · Exclusive-create on a file that already exists
file = open("notes.txt", "x")
Traceback (most recent call last):
  File "/tmp/awm_lesson11/work/mistake4.py", line 1, in <module>
    file = open("notes.txt", "x")
FileExistsError: [Errno 17] File exists: 'notes.txt'

This is exactly what "x" promises to do. If the path is already occupied, Python refuses to replace it.

Supporting classroom explanations

This page is original A Wandering Mind instructional material. The CPSC 1301K lectures below reinforce the overall file-I/O model and the mechanics of opening a file.

Files Overview — by Hyrum Carroll · 5:09. Watch on YouTube ↗ · CPSC 1301K playlist ↗

What it adds: a classroom-level overview of why programs use files and how file I/O fits into the larger flow of program data.

Opening Files — by Hyrum Carroll · 4:50. Watch on YouTube ↗ · CPSC 1301K playlist ↗

What it adds: a focused walkthrough of supplying a filename and access mode to create a usable file object.

Try it yourself

These exercises assume the named example files exist where required. Focus on predicting whether the operation is opening an existing file or asking Python to create a new one.

Exercise 1 · Open a journal for reading

Assume journal.txt already exists. Open it in read mode with UTF-8 encoding, print the mode, then close the file.

Show one answer
file = open("journal.txt", "r", encoding="utf-8")
print(file.mode)
file.close()
r

Exercise 2 · Open a file in a subfolder

Assume scores.txt exists inside a folder named data. Open it for reading and print the file object’s name.

Show one answer
file = open("data/scores.txt", "r", encoding="utf-8")
print(file.name)
file.close()
data/scores.txt

Exercise 3 · Require a brand-new file

Assume draft.txt does not exist. Open it in exclusive-create mode, print the mode, then close it.

Show one answer
file = open("draft.txt", "x", encoding="utf-8")
print(file.mode)
file.close()
x

What you should carry into Lesson 12

You now know that open() connects Python to a filesystem path and returns a file object. Relative paths depend on the current working directory, file modes control the requested kind of access, text and binary modes represent different data models, and some modes can create or even truncate files.

The next lesson focuses on the lifetime of that open resource. Continue to Verifying a File Opened, and Closing It Properly, where you will compare manual close() calls with Python’s safer with open(...) as file: context-manager pattern.