1.3.3 · D1Python Intermediate

Foundations — File I - O — open modes (r, w, a, rb), read, readline, readlines, write

2,679 words12 min readBack to topic

Before you can trust a single line of the parent note, you need to know what every word and symbol in it actually means and what picture it stands for. This page builds them one at a time, each leaning on the one before. If a term appears in the parent, it is defined here first.


0. The most basic thing: what IS a file?

Look at the strip below. The numbers under each box are its position (we call this the offset — how far from the start). The numbers inside the boxes are the bytes.

Figure — File I - O — open modes (r, w, a, rb), read, readline, readlines, write

Why we need this picture: every later idea — "finger position", "read", "EOF", "seek" — is a statement about positions on this strip. If you can see the strip, the rest is easy.


1. From numbers to letters: encoding

The strip only holds numbers, but you want to store the word apple. So we need an agreed table that says "the letter a shall be stored as the number 97, b as 98, …".

Figure — File I - O — open modes (r, w, a, rb), read, readline, readlines, write

This is exactly why the topic distinguishes text mode (numbers → letters for you, using an encoding) from binary mode (raw numbers, no translation). See Strings and Encoding (UTF-8) and Bytes vs str for the full table.


2. str vs bytes — the two things a read can return

Figure — File I - O — open modes (r, w, a, rb), read, readline, readlines, write

When the parent writes f.read(8) giving b'\x89PNG\r\n\x1a\n', the b tells you: these are raw bytes, do not read them as words. The \x89 means "the single byte whose number is ".


3. The newline symbol \n (and its Windows cousin \r\n)

Figure — File I - O — open modes (r, w, a, rb), read, readline, readlines, write

Why the topic obsesses over \n: the whole difference between read, readline, and readlines is where they stop relative to the \n boxes. readline() stops right after the next \n; readlines() splits the strip at every \n. You cannot understand those three methods without seeing where the \n boxes sit.

But here is a real-world twist you must know:

Figure — File I - O — open modes (r, w, a, rb), read, readline, readlines, write

4. The cursor (file position)

Figure — File I - O — open modes (r, w, a, rb), read, readline, readlines, write

This is the single fact that explains every "surprise" in the parent:

  • Why a second f.read() returns '' → the finger is already past the last box (at EOF).
  • Why readline() twice gives line 1 then line 2 → the finger remembers where it stopped.
  • Why f.seek(0) re-reads → it drags the finger back to box .

5. Direction and start-position: what a "mode" encodes

A mode is the tiny string you pass to open() that answers, all at once: read or write? keep or wipe? start or end? letters or raw bytes? Now every ingredient has a picture — see the strip figure below the table:

Symbol Plain meaning Picture on the strip
r read only finger at box , can only pull bytes out; file must exist
w write, wipe first strip emptied to length , finger at box
a append finger jumps to EOF, can only push bytes on the end
x exclusive create like w, but refuses (error) if the file already exists
t text (default) boxes run through UTF-8 → you get str; newlines translated
b binary boxes handed over as raw numbers → bytes; no translation
+ read AND write finger can both pull and push
Figure — File I - O — open modes (r, w, a, rb), read, readline, readlines, write

6. The with block and try/except — why they hover in the background

Errors like "file not found" (from r on a missing file) or "file already exists" (from x) are handled with Exceptions try-except, and building the path string safely ("folder/notes.txt") is the job of os and pathlib.


Prerequisite map

File = strip of numbered boxes

Byte = one box 0 to 255

Encoding UTF-8 turns letters into bytes

str vs bytes via b prefix

Newline LF byte 10 vs CRLF

Text mode translates newlines

Cursor = finger position

EOF = past the last box

seek moves finger by hand

Modes r w a x t b

read readline readlines write

with block closes and flushes

File I O topic

Read it top-down: the strip gives us bytes, bytes give us encoding and thus str/bytes, the newline (and its CRLF/LF flavours) lets us talk about lines, the cursor and seek let us talk about where, and all of these feed the modes and read/write methods — which the with block finally makes safe.


Equipment checklist

Test yourself — reveal only after you have answered aloud.

A file on disk physically is…
a finite, ordered sequence of numbered boxes, each holding one byte (a number 0–255).
A byte can hold which range of values, and why that range?
0 to 255, because 8 on/off switches give combinations.
What does an encoding like UTF-8 do?
Maps characters to bytes (encode) and bytes back to characters (decode).
How do you tell str from bytes when Python prints them, and what does the b really label?
bytes has a leading b (e.g. b'apple'); str does not. The b labels the container's promise (raw numbers vs UTF-8 letters), not the stored boxes.
\n is how many characters, and what byte number?
One character, byte number 10 (LF).
What is CRLF and where does it appear?
\r\n — two bytes, 13 then 10 — the Windows line ending; text mode translates it to a single \n on read.
What does binary mode do about newline translation?
Nothing — rb/wb give you the raw bytes including any \r (13).
What is the cursor, and what moves it?
A number saying which box the finger points at; every read or write advances it, and seek moves it by hand.
What happens on seek to a negative offset, and past EOF?
Negative → error (no box before 0). Past EOF → allowed; reads give empty, writing there leaves a zero-filled gap.
What is EOF and what does a read at EOF return?
The position just past the last box; returns '' (text) or b'' (binary).
What do modes x and t mean?
x = exclusive create (error if the file already exists); t = text mode, the invisible default (gives str, translates newlines).
What three things does a mode string decide (plus text/binary)?
Direction (read/write), keep or wipe/create, starting position (start or end); plus text vs binary via b (default t).
Why must you declare intent (the mode) before moving data?
The OS prepares the strip differently — erase for w, seek end for a, refuse-if-missing for r, refuse-if-exists for x — before any byte moves.
What guarantees a file is closed and its buffer flushed even on error?
The with open(...) as f: context manager.