Writing Files
Creating and writing files is essential for saving program output, generating reports,
logging events, and persisting data. Python provides intuitive methods for writing text and binary
files. Understanding the difference between write mode ('w') which overwrites and append
mode ('a') which adds to existing content is crucial - choosing wrong can destroy your data!
Write Modes
The mode parameter in open() determines how files are created and written. Write mode
('w') creates a new file or completely overwrites an existing one - all
previous content is lost! Append mode ('a') is safer when you want to add to existing
content. Exclusive create mode ('x') prevents accidental overwrites.
Click Run to execute your code
'w') destroys existing content
without warning! If you open an important file in write mode, all its data is gone the moment you
call open() - even before you write anything. Always double-check your mode when
working with existing files.
Write Methods
Python provides two main methods for writing: write() writes a single string and returns
the number of characters written, while writelines() writes a list of strings. Important:
neither method adds newlines automatically - you must include \n yourself!
Click Run to execute your code
write(string) - Writes one string, returns character countwritelines(list) - Writes list of strings, returns NoneNeither adds newlines! You must include
\n in your strings.For large data,
writelines() with a generator is memory-efficient.
Writing Binary Files
Binary mode ('wb') writes raw bytes instead of text. This is essential for images,
audio, compressed files, and any non-text data. You must write bytes or bytearray
objects, not strings. Use encode() to convert strings to bytes, or the struct
module for structured binary data.
Click Run to execute your code
- Images (PNG, JPEG, GIF)
- Audio/Video files
- Compressed archives (ZIP, GZIP)
- Executables and compiled code
- Network protocols and serialized data
- Any file where exact byte representation matters
Formatted File Output
Often you need to write formatted data - tables, reports, or structured text. Python offers several
ways to format output: f-strings for inline formatting, format() for templates, and even
print() with the file parameter. For efficiency with many lines, join them
into one string before writing.
Click Run to execute your code
Common Mistakes
1. Accidentally overwriting important files
# DISASTER - overwrites config file!
with open("config.txt", "w") as f:
f.write("debug=true") # Lost all other settings!
# Safe approach - read first, modify, write back
with open("config.txt", "r") as f:
content = f.read()
# Modify content...
with open("config.txt", "w") as f:
f.write(modified_content)
# Or use append mode to add settings
with open("config.txt", "a") as f:
f.write("\ndebug=true")
2. Forgetting newlines with writelines()
# Wrong - creates one long line!
lines = ["apple", "banana", "cherry"]
with open("fruits.txt", "w") as f:
f.writelines(lines) # Result: "applebananacherry"
# Correct - add newlines
lines = ["apple\n", "banana\n", "cherry\n"]
with open("fruits.txt", "w") as f:
f.writelines(lines)
# Or use generator expression
lines = ["apple", "banana", "cherry"]
with open("fruits.txt", "w") as f:
f.writelines(line + "\n" for line in lines)
3. Writing strings to binary files
# Wrong - TypeError: a bytes-like object is required
with open("data.bin", "wb") as f:
f.write("Hello") # Error!
# Correct - encode string to bytes
with open("data.bin", "wb") as f:
f.write("Hello".encode("utf-8"))
# Or use bytes literal
with open("data.bin", "wb") as f:
f.write(b"Hello")
4. Not flushing or closing files
# Wrong - data may not be written yet!
f = open("log.txt", "w")
f.write("Important data")
# Program crashes here - data may be lost!
# Correct - use 'with' statement
with open("log.txt", "w") as f:
f.write("Important data")
# Automatically closed and flushed
# Or manually flush for long-running programs
f = open("log.txt", "w")
f.write("Log entry")
f.flush() # Force write to disk now
5. Writing many small strings inefficiently
# Slow - many small write calls
with open("output.txt", "w") as f:
for i in range(10000):
f.write(f"Line {i}\n") # 10000 write calls!
# Fast - build string first, single write
lines = [f"Line {i}" for i in range(10000)]
with open("output.txt", "w") as f:
f.write("\n".join(lines)) # One write call!
# Or use writelines with generator
with open("output.txt", "w") as f:
f.writelines(f"Line {i}\n" for i in range(10000))
Exercise: Log File Writer
Task: Create a simple log file writer that appends timestamped entries.
Requirements:
- Write a function that appends log entries with timestamps
- Each entry should be on its own line
- Include the log level (INFO, WARNING, ERROR)
- Demonstrate with multiple log entries
Click Run to execute your code
Show Solution
from datetime import datetime
import os
def log_message(filename, level, message):
"""Append a timestamped log entry to a file."""
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
entry = f"[{timestamp}] {level}: {message}\n"
with open(filename, "a") as f:
f.write(entry)
# Test the logger
log_file = "app.log"
# Write some log entries
log_message(log_file, "INFO", "Application started")
log_message(log_file, "INFO", "User logged in: alice")
log_message(log_file, "WARNING", "Low memory: 85% used")
log_message(log_file, "ERROR", "Database connection failed")
log_message(log_file, "INFO", "Retrying connection...")
log_message(log_file, "INFO", "Connection restored")
# Read and display the log
print("=== Log Contents ===")
with open(log_file, "r") as f:
print(f.read())
# Cleanup
os.remove(log_file)
Summary
- Write mode:
open("file", "w")- overwrites existing content - Append mode:
open("file", "a")- adds to end of file - Exclusive create:
open("file", "x")- fails if file exists - Write string:
f.write("text")- returns char count - Write list:
f.writelines(["a", "b"])- no auto newlines! - Binary write:
open("file", "wb")withbytes - Print to file:
print("text", file=f) - Force flush:
f.flush()- writes buffer to disk - Always use:
with open(...) as f:for auto-close - Efficiency: Join strings before writing for better performance
What's Next?
Now that you can read and write files, let's learn about context managers - the
Pythonic way to handle resources. The with statement ensures files are properly closed
even when errors occur, and you can create your own context managers for other resources!
Enjoying these tutorials?