Writing a text file uses the same open and with you saw in the last lesson — with a different mode.
Two modes for writing
"w"— write, overwriting the file if it exists. If the file doesn’t exist, it’s created."a"— append, adding to the end of an existing file (or creating a new one).
with open("output.txt", "w", encoding="utf-8") as f:
f.write("First line\n")
f.write("Second line\n")
If output.txt already had content, it’s gone. "w" always starts fresh.
.write() vs .writelines()
f.write(text) writes one string. It does not add a newline — you must include \n yourself:
with open("notes.txt", "w", encoding="utf-8") as f:
f.write("Hello\n")
f.write("World\n")
Hello
World
f.writelines(list_of_strings) writes every string in the list (still no automatic newlines):
lines: list[str] = ["Hello\n", "World\n", "Goodbye\n"]
with open("notes.txt", "w", encoding="utf-8") as f:
f.writelines(lines)
If your lines don’t already have newlines, add them:
lines: list[str] = ["Hello", "World", "Goodbye"]
with open("notes.txt", "w", encoding="utf-8") as f:
f.write("\n".join(lines))
f.write("\n") # trailing newline at the end of the file
"\n".join(lines) is the standard idiom for joining a list of lines.
Appending — "a" mode
If you want to add to a file instead of overwriting:
with open("log.txt", "a", encoding="utf-8") as f:
f.write("New entry\n")
Each run adds a new line to the bottom. The previous content is preserved. This is exactly how log files work.
print() to a file
print() accepts a file argument — anything you can call .write() on:
with open("output.txt", "w", encoding="utf-8") as f:
print("Hello", file=f)
print("World", file=f)
print(42, file=f)
The benefits over f.write():
- Automatic newline at the end of each call (matches the terminal version).
- Automatic string conversion (
print(42, ...)works;f.write(42)raises aTypeError). - Same
sepandendarguments you already know.
For most simple writes, this is the cleanest form.
A complete example — saving a result
A program that asks the user for a sentence and saves it to a file:
sentence: str = input("Type a sentence: ")
with open("sentences.txt", "a", encoding="utf-8") as f:
print(sentence, file=f)
print("Saved.")
Run it a few times. Open sentences.txt. Each run appends one line.
Writing structured data
You can write any string to a text file — including JSON or CSV. Python has dedicated modules for both (the next two lessons), but for one-off cases you can serialise by hand:
data: dict[str, int] = {"score": 95, "tries": 3}
with open("data.txt", "w", encoding="utf-8") as f:
for key, value in data.items():
print(f"{key}={value}", file=f)
score=95
tries=3
For real config or data exchange, use the dedicated modules — they handle escaping, quoting, and types correctly.
What if the directory doesn’t exist?
open(path, "w") will create the file, but not the folder it lives in:
open("logs/2026/output.txt", "w")
# FileNotFoundError: [Errno 2] No such file or directory: 'logs/2026/output.txt'
Create the folder first:
from pathlib import Path
path = Path("logs/2026/output.txt")
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text("Hello\n", encoding="utf-8")
Path.write_text is a one-liner shortcut for “open in w mode, write, close”. Convenient when you don’t need to write in chunks.
We’ll cover pathlib thoroughly later in this section.
What’s next
You can read and write text. Next — CSV files, the most common spreadsheet format.