Text files are one of the simplest ways to exchange information between programs. Configuration files, logs, reports, exported notes, and small datasets are often stored as plain text because the format is easy to inspect and works across operating systems. Learning how to work with Python text files gives you a practical foundation for automation, data processing, and larger applications.
This guide explains how to open, read, write, append, and process text safely. The examples use modern Python practices: the with statement, explicit UTF-8 encoding, and pathlib when a path object makes the code clearer. You can follow along even if you are still learning the basics in our Python beginner guide.
How text files work in Python
Python treats a text file as a stream of Unicode characters. The built-in open() function creates a file object that can read from or write to that stream. A file mode tells Python what you intend to do: r reads, w writes and replaces existing content, a appends, and x creates a new file only when it does not already exist.
Text mode returns strings and performs encoding and newline conversion. Binary mode returns bytes and is appropriate for images, executables, compressed archives, and other non-text data. The official Python file tutorial recommends specifying an encoding for predictable behavior across platforms.
Read an entire text file
The simplest approach is read(). It returns all remaining text as one string. Always use a context manager so the file is closed even if an error occurs.
from pathlib import Path
path = Path("notes.txt")
with path.open("r", encoding="utf-8") as file:
content = file.read()
print(content)This technique is convenient for small and medium files. For a very large log or export, reading everything at once can consume unnecessary memory. In that situation, process one line at a time instead.
Process a file line by line
A file object is iterable, so a regular for loop reads successive lines efficiently. The line normally includes its ending newline. Calling strip() removes leading and trailing whitespace, while rstrip() can remove only the trailing side.
from pathlib import Path
path = Path("tasks.txt")
with path.open(encoding="utf-8") as file:
for number, line in enumerate(file, start=1):
task = line.strip()
if task:
print(f"{number}: {task}")Using enumerate() adds line numbers without maintaining a manual counter. It is also useful when reporting malformed data. Our guide to enumerate in Python loops covers this pattern in more detail.
Read lines into a list
The readlines() method returns a list, but a list comprehension usually makes cleanup easier. The following example ignores blank lines and stores normalized values.
from pathlib import Path
with Path("names.txt").open(encoding="utf-8") as file:
names = [line.strip() for line in file if line.strip()]
print(names)This is a natural use of a Python list comprehension. Keep the expression readable: if filtering and transformation become complicated, a normal loop is often the better choice.
Write a new text file
Open a file with mode w to create it or replace its current contents. The write() method does not add a newline automatically, so include line endings yourself when needed.
from pathlib import Path
report = """Weekly report
Completed: 12
Pending: 3
"""
Path("report.txt").write_text(report, encoding="utf-8")The Path.write_text() convenience method opens, writes, and closes the file in one operation. For several incremental writes, use a context manager instead.
from pathlib import Path
items = ["keyboard", "monitor", "mouse"]
with Path("inventory.txt").open("w", encoding="utf-8") as file:
for item in items:
file.write(f"{item}\n")Append without deleting existing content
Mode a positions new output at the end of the file. It is useful for simple logs, audit trails, and collections that grow over time. Because append mode preserves old data, it is safer than accidentally opening an important file with w.
from datetime import datetime
from pathlib import Path
message = "Backup completed"
timestamp = datetime.now().isoformat(timespec="seconds")
with Path("activity.log").open("a", encoding="utf-8") as file:
file.write(f"{timestamp} - {message}\n")For production applications, prefer the standard Python logging module, which supports severity levels, formatting, file rotation, and multiple output handlers.
Handle missing files and decoding errors
File operations can fail. A path may not exist, permissions may be insufficient, or the text may use a different encoding. Catch only the exceptions you know how to handle, and provide useful context instead of hiding every error.
from pathlib import Path
path = Path("settings.txt")
try:
text = path.read_text(encoding="utf-8")
except FileNotFoundError:
print(f"File not found: {path}")
except UnicodeDecodeError:
print("The file is not valid UTF-8 text.")
except PermissionError:
print(f"Permission denied: {path}")
else:
print(text)The articles on FileNotFoundError and UnicodeDecodeError explain how to diagnose these situations. Avoid using a broad except Exception unless you re-raise or log the original exception.
Use pathlib for clearer paths
The pathlib module represents paths as objects and works consistently on Windows, macOS, and Linux. You can test whether a file exists, inspect its suffix, create parent folders, and combine directory names without manually choosing slash characters.
from pathlib import Path
output = Path("exports") / "summary.txt"
output.parent.mkdir(parents=True, exist_ok=True)
output.write_text("Export finished successfully.", encoding="utf-8")
print(output.resolve())For more path operations, see the complete guide to managing files with pathlib.
A practical word-count project
The following program reads a document, normalizes words, and prints the most frequent terms. It combines file handling, string methods, regular expressions, and Counter.
import re
from collections import Counter
from pathlib import Path
text = Path("article.txt").read_text(encoding="utf-8").lower()
words = re.findall(r"[a-z']+", text)
counts = Counter(words)
for word, amount in counts.most_common(10):
print(f"{word}: {amount}")This small project can become a search index, readability checker, or content-analysis tool. The Counter tutorial shows additional frequency-analysis techniques.
Common mistakes to avoid
- Forgetting that
wreplaces the existing file. - Relying on the operating system’s default encoding instead of declaring UTF-8.
- Opening images or archives in text mode.
- Reading a multi-gigabyte file entirely into memory.
- Building paths with hard-coded slash characters.
- Leaving a file open instead of using
with.
Frequently asked questions
Should I use open() or pathlib?
Both are valid. open() is universal and explicit. Path.open(), read_text(), and write_text() are often clearer when the rest of your code already uses path objects.
Why use encoding=”utf-8″?
The default encoding can differ between systems. Declaring UTF-8 makes the program more portable and reduces failures when text contains accents, symbols, or characters from other languages.
How do I preserve a file while adding new text?
Use append mode, a. When you need to modify content in the middle, read the data, transform it, and safely write a replacement file—often through a temporary file.
Final thoughts
Python text files are simple, but the habits you use around them matter. Prefer context managers, explicit encodings, clear path handling, and specific exception handling. Once these foundations are comfortable, moving to structured formats such as CSV and JSON becomes much easier.






