runtime
92 / 250
lesson 92 Files & Directories · intermediate

Start fresh or add to the end

Mode "w" empties a file before writing, mode "a" keeps what is there and adds to the end, and mode "x" refuses to touch a file that already exists.

You'll be able to
  • Explain what "w", "a" and "x" do to a file that already exists
  • Append one line per event to a log without losing earlier lines
  • Write a report that is correct no matter how many times the program runs
The idea

Opening a file to write always raises a question: what happens to what's already in it? The mode answers it.

  • "w" (write) creates the file, or empties it first if it exists.
  • "a" (append) creates the file, or keeps its text and writes after it.
  • "x" (exclusive) creates the file, and raises FileExistsError if it already exists.

A log grows with every event, so it uses "a". A daily report should describe today only, so it uses "w". An invoice that must never be silently replaced uses "x".

Run each example to see what it prints. Running examples doesn't count toward progress.

example-1.py · An activity log that grows
def log_event(path, message):
    log = open(path, "a", encoding="utf-8")
    log.write(message + "\n")
    log.close()

log_event("activity.log", "08:59 store opened")
log_event("activity.log", "09:14 order O100043 packed")
log_event("activity.log", "09:40 order O101217 packed")

log = open("activity.log", encoding="utf-8")
print(log.read(), end="")
log.close()

A report is the opposite job. If it appended, running the program twice would put two reports in one file. With "w" every run replaces the old contents, so the file always describes the latest run.

example-2.py · A daily report that starts fresh
def write_report(path, orders):
    delivered = 0
    for order in orders:
        if order["status"] == "delivered":
            delivered += 1
    report = open(path, "w", encoding="utf-8")
    report.write(f"orders: {len(orders)}\n")
    report.write(f"delivered: {delivered}\n")
    report.close()

orders = [
    {"order_id": "O100043", "status": "delivered"},
    {"order_id": "O108024", "status": "cancelled"},
    {"order_id": "O108752", "status": "delivered"},
]
write_report("daily.txt", orders)
write_report("daily.txt", orders)

report = open("daily.txt", encoding="utf-8")
print(report.read(), end="")
report.close()
example-3.py · x refuses to replace a file
first = open("invoice_536374.txt", "x", encoding="utf-8")
first.write("Invoice 536374: 32 x VICTORIAN SEWING BOX LARGE\n")
first.close()
second = open("invoice_536374.txt", "x", encoding="utf-8")

When to use which: "a" for logs and records that accumulate, "w" for output that is rebuilt from scratch each time, "x" when overwriting would destroy something. Mistakes to avoid: opening with "w" inside a loop (each pass wipes the previous pass's line), and appending to a report, which duplicates it on every run.

Review
  • "w" empties or creates, "a" keeps and adds, "x" creates or raises FileExistsError.
  • Logs append; rebuilt reports and exports write fresh, so running twice gives the same file.
  • Opening with "w" inside a loop keeps only the last pass.
  • Next: let with close files for you, and read a file one line at a time.

Loading your progress…

To master this lesson, solve both challenges without hints or the answer, and pass the concept check.

Start fresh or add to the end — Files & Directories · Runtime