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() 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 a TypeError).
  • Same sep and end arguments 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.

Toggle theme (T)