Learn how to safely create, write, and save text files in Python using the context manager pattern.
What it is
In Python, file handling involves interacting with the operating system's file system. The core object is a file handle, which acts as an interface between your program and the disk. When you "write" to a file, you are sending data from memory to storage. The most critical concept here is resource management: ensuring that files are properly closed after use to prevent data loss or system errors.
Related terms include mode (how the file is opened), buffering (temporary storage before writing to disk), and encoding (character set used for text).
Why it matters
- Data Persistence: Allows programs to save results, logs, or configurations that survive after the script ends.
- Interoperability: Enables Python scripts to exchange data with other applications via standard formats like CSV, JSON, or plain text.
- Safety: Proper file handling prevents "file locked" errors and ensures all buffered data is flushed to the disk.
- Automation: Essential for batch processing tasks, such as renaming thousands of files or generating reports.
Syntax or steps
The recommended syntax uses the with statement combined with the built-in open() function. This creates a context manager that automatically closes the file when the block exits, even if an error occurs.
- Call
open(filename, mode). Common modes are'w'(write/create) and'a'(append). - Assign the result to a variable (conventionally
forfile) usingas. - Use methods like
.write()or.writelines()inside the indented block. - Exit the block; Python handles closing the file.
Example
# Create and write to a new file
filename = "report.txt"
try:
# 'w' mode creates the file if it doesn't exist,
# or truncates (empties) it if it does.
with open(filename, "w", encoding="utf-8") as f:
f.write("Hello, World!\n")
f.write("This is line two.\n")
print(f"Successfully wrote to {filename}")
except IOError as e:
print(f"An error occurred: {e}")
Explanation:
1. We define the target filename.
2. Inside the with block, open() returns a file object assigned to f. The encoding="utf-8" argument ensures special characters are handled correctly across different systems.
3. f.write() adds strings to the file buffer. Note that \n is required for new lines; write() does not add them automatically.
4. Once the indentation ends, the file is closed and saved to disk.
Common mistakes
- Forgetting to close: Using
f = open(...)withoutf.close()can lead to data loss if the script crashes. Always usewith. - Overwriting unintentionally: Mode
'w'deletes existing content. Use'a'if you want to keep previous data. - Missing newlines: Calling
f.write("line 1")followed byf.write("line 2")results in "line 1line 2". You must explicitly add\n. - Path issues: Trying to write to a directory that doesn't exist raises an error. Ensure parent directories exist before opening the file.
When to use it
Compare direct file writing with higher-level libraries depending on your needs.
| Method | Best For | Complexity |
|---|---|---|
open() / .write() |
Raw text, logs, simple config files | Low |
json.dump() |
Structured data dictionaries/lists | Medium |
pandas.to_csv() |
Large tabular datasets | High (requires library) |
Practice
Guided Exercise: Write a script that creates a file named numbers.txt containing the numbers 1 through 5, each on a separate line.
Challenge: Modify the script to append the number 6 to the same file without deleting the previous content.
Hint: For the challenge, change the mode from 'w' to 'a'.
Quick check
Q: What happens if you try to open a file in mode 'r' (read) but the file does not exist?
A: Python raises a FileNotFoundError. Mode 'r' expects the file to already be present on disk.
Summary
Using the with open(...) context manager is the safest and most Pythonic way to handle files. It guarantees resource cleanup and simplifies code structure. Remember to choose the correct mode ('w' vs 'a') and explicitly manage line breaks when writing text.