Reading and writing files with open()
Overview
`open(path, mode, encoding=...)` returns a file object you read from or write to, and you almost always use it with a `with` block so it closes automatically — even if an error is raised mid-way. with open('notes.txt', 'w', encoding='utf-8') as f: f.write('hello\n') with open('notes.txt', 'r', encoding='utf-8') as f: text = f.read() The mode string picks the operation: `'r'` read (default), `'w'` write (truncates!), `'a'` append, `'x'` create-or-fail, and a `'b'` suffix (`'rb'`, `'wb'`) for raw bytes instead of text. For text files, iterating the file object yields one line at a time, which streams a huge file without loading it all into memory.
Every program eventually touches files — reading config, writing logs, processing data exports. Doing it correctly (closing handles, choosing the right mode, setting an explicit encoding) prevents corrupted output, locked files, and the classic 'works on my machine' encoding bugs.
Where used: Reading config and data files, Writing logs and reports, ETL / data processing scripts
Why learn this
- Reading input data and writing results is the backbone of almost every script and batch job.
- Knowing that `'w'` truncates and that `with` guarantees closing prevents real data-loss and resource-leak bugs.
Code walkthrough
with open('demo.txt', 'w', encoding='utf-8') as f:
f.write('line 1\n')
f.write('line 2\n')
total = 0
with open('demo.txt', 'r', encoding='utf-8') as f:
for line in f:
total += 1
print(total)
Focus: for line in f (streaming one line at a time, so total counts lines)
Common mistakes
- Opening in 'w' when you meant to append: `'w'` truncates the file to empty the instant it's opened — before you write anything. If you want to add to existing content, use `'a'`. Reaching for `'w'` on a file you care about silently destroys it.
- Not using with (leaking the handle): A bare `f = open(...)` without `f.close()` leaves the OS handle open until garbage collection — on Windows this can lock the file, and buffered writes may not be flushed to disk. `with` closes and flushes deterministically.
- Relying on the default encoding: Without `encoding='utf-8'`, Python uses a platform default that differs across OSes, so a file written on one machine can fail to decode on another. Always pass an explicit encoding for text.
Glossary
- context manager
- An object used with `with` that sets up and guarantees cleanup of a resource. Example: `with open('f') as fh:` closes the file automatically.
- encoding
- The rule mapping text characters to bytes on disk, such as UTF-8. Example: `open('f', encoding='utf-8')`.
Recall questions
- What does opening a file in `'w'` mode do to existing contents?
- Why is `with open(...) as f:` preferred over a bare `open()`?
- How do you read a large file line by line without loading it all into memory?
Understanding checks
What does this print?
second
The second `open(..., 'w')` truncates the file before writing, so 'first' is gone. Only 'second' remains. If the goal was to keep both, the second open should use `'a'`.
Why might text written inside a bare `f = open('x','w'); f.write('hi')` (with no `close()` and no `with`) not appear in the file if the program crashes right after?
Writes are buffered in memory and only flushed to disk on close/flush; without `with` or `close()`, a crash can lose the buffered data.
File objects buffer writes for efficiency. `with` (or an explicit `close()`) flushes the buffer and releases the OS handle deterministically; skipping it risks unflushed, lost writes.
Practice tasks
Append without clobbering
The script below overwrites `log.txt` every run because it opens in `'w'`. Change it so each run adds a new line and keeps previous lines. Then read the whole file back and print it.
Continue learning
Next: pathlib for filesystem paths