Python Tutorial / Read and Write Text Files with with and Encodings
Open text files with an explicit encoding and use with to close them when the block exits. The w mode truncates an existing file, so distinguish creating new output from replacing data you need to preserve.
Choose the mode and encoding
| Mode | Purpose | Existing-file behavior |
|---|---|---|
| r | Read | Fails if missing |
| w | Write replacement content | Truncates existing content |
| a | Append | Creates the file if absent |
| x | Create only | Fails if already present |
An encoding maps bytes to text. Specify encoding="utf-8" for UTF-8 data rather than relying on an environment default. errors="ignore" can discard unreadable input, so it should not be a general way to hide decoding failures.
For the relevant APIs and platform requirements, see Python: inputoutput.
Paths and recovery from file errors build on the rules demonstrated in Handle Exceptions with try, except, else, finally and raise.
Write, append and read a complete file
Use a disposable practice folder. The program resets notes-demo.txt with w on each run.
Save the complete code below as text_files.py in a separate practice folder, using UTF-8. Run python text_files.py in a terminal with your project virtual environment selected. Outside a virtual environment on macOS or Ubuntu, use python3 when that is your interpreter command.
from pathlib import Path
path = Path("notes-demo.txt")
with path.open("w", encoding="utf-8", newline="\n") as f:
f.write("coffee:3500\n")
f.write("lunch:8000\n")
with path.open("a", encoding="utf-8") as f:
f.write("bus:2500\n")
with path.open("r", encoding="utf-8") as f:
for line in f:
print(line.rstrip("\n"))
Expected output:
coffee:3500 lunch:8000 bus:2500
Choose whole-file or line-based reading
read() returns the remaining content as a string. Iterating for line in f processes one line at a time and avoids loading the whole file when that is unnecessary. After iteration reaches the end, reopen the file or deliberately seek before trying to read it again.
strip() removes surrounding whitespace, including meaningful spaces. If only the newline should be removed, restrict the operation, for example to rstrip("\n"). File opening and newline settings can also translate line endings.
For FileNotFoundError inspect the resolved path and working directory; for UnicodeDecodeError inspect the actual encoding; for PermissionError inspect permissions, locks and whether the target is a directory. Replacing every failure with an empty string loses the distinction between missing and empty data. Handle only errors for which a recovery policy is defined.
Protect originals and diagnose file errors
For important data, consider writing to a separate temporary file, validating it and replacing the destination only when appropriate. A with block closes the file; it does not restore content already truncated before a write failure.
For FileNotFoundError, check the path and parent folder. For PermissionError, check permissions and possible application locks. For UnicodeDecodeError, identify the file’s actual encoding rather than discarding bytes. Change the initial w to a and observe duplicated records on a second run, then restore the example.
The pathlib guide helps establish which file is being opened before investigating its content or encoding.




