File I/O
So far, our program data has only existed in memory — close the program, and the data is lost. File I/O allows programs to save data to disk and read it back on the next startup. This is a fundamental capability for any practical application.
1. Opening and Closing Files
The basic file operation has three steps: open -> read/write -> close.
Example: Manually Opening and Closing a File
# Write to a file
file = open("hello.txt", "w", encoding="utf-8")
file.write("Hello, World!")
file.close()
# Read from a file
file = open("hello.txt", "r", encoding="utf-8")
content = file.read()
file.close()
print(content) # Hello, World!
Warning: Always remember
close()! Open files consume system resources. Forgetting to close can lead to file corruption or resource exhaustion. But don't worry — the next section has a better approach.
2. The with Statement (Context Manager)
The with statement automatically closes the file at the end of the code block, without needing to call close():
Example: Safe File I/O with with
# Write
with open("hello.txt", "w", encoding="utf-8") as f:
f.write("Hello, World!")
# Read
with open("hello.txt", "r", encoding="utf-8") as f:
content = f.read()
print(content)
Tip: Always use
withfor file operations. It's the safest, most Pythonic way — the file is correctly closed whether or not an exception occurs in the code block.
3. File Open Modes
The second parameter of open() is the mode:
| Mode | Meaning | File Exists | File Doesn't Exist |
|---|---|---|---|
"r" |
Read (default) | Read normally | Error |
"w" |
Write | Clear then write | Create |
"a" |
Append | Append to end | Create |
"x" |
Exclusive create | Error | Create |
"r+" |
Read and write | Readable and writable | Error |
Example: Different File Open Modes
# "w" — write (clear and rewrite)
with open("test.txt", "w", encoding="utf-8") as f:
f.write("First line\n")
f.write("Second line\n")
# "a" — append
with open("test.txt", "a", encoding="utf-8") as f:
f.write("Third line\n")
# "r" — read
with open("test.txt", "r", encoding="utf-8") as f:
print(f.read())
Output:
First line
Second line
Third line
4. Ways to Read Files
Example: Three Ways to Read a File
# Assume file content:
# First line
# Second line
# Third line
# Method 1: read() — read all at once
with open("test.txt", "r", encoding="utf-8") as f:
content = f.read()
print(content)
# Method 2: readlines() — read as a list
with open("test.txt", "r", encoding="utf-8") as f:
lines = f.readlines()
print(lines) # ['First line\n', 'Second line\n', 'Third line\n']
# Method 3: line by line (recommended)
with open("test.txt", "r", encoding="utf-8") as f:
for line in f:
print(line.strip()) # strip() removes newline characters
Example: File Backup Tool (Difficulty: Star-Star)
def backup_file(filename):
"""Create a backup copy of a file"""
try:
with open(filename, "r", encoding="utf-8") as f:
content = f.read()
backup_name = filename + ".bak"
with open(backup_name, "w", encoding="utf-8") as f:
f.write(content)
print(f"Backup created: {backup_name}")
except FileNotFoundError:
print(f"File {filename} does not exist!")
backup_file("test.txt")
5. Reading and Writing CSV Files
CSV (Comma-Separated Values) is the most common data exchange format. Python has a built-in csv module:
Example: CSV File I/O
import csv
# Write CSV
data = [
["Name", "Age", "City"],
["Zhang San", 25, "Beijing"],
["Li Si", 30, "Shanghai"],
["Wang Wu", 22, "Guangzhou"],
]
with open("students.csv", "w", newline="", encoding="utf-8") as f:
writer = csv.writer(f)
writer.writerows(data)
# Read CSV
with open("students.csv", "r", encoding="utf-8") as f:
reader = csv.reader(f)
for row in reader:
print(row)
Output:
['Name', 'Age', 'City']
['Zhang San', '25', 'Beijing']
['Li Si', '30', 'Shanghai']
['Wang Wu', '22', 'Guangzhou']
Using DictReader/DictWriter (More Intuitive)
Example: DictReader/DictWriter for CSV
import csv
# Write
data = [
{"name": "Zhang San", "age": 25, "city": "Beijing"},
{"name": "Li Si", "age": 30, "city": "Shanghai"},
]
with open("students_dict.csv", "w", newline="", encoding="utf-8") as f:
fieldnames = ["name", "age", "city"]
writer = csv.DictWriter(f, fieldnames=fieldnames)
writer.writeheader() # Write header
writer.writerows(data) # Write data rows
# Read
with open("students_dict.csv", "r", encoding="utf-8") as f:
reader = csv.DictReader(f)
for row in reader:
print(f"{row['name']} — {row['age']} years old, from {row['city']}")
6. Path Handling
Use os.path or pathlib for file path handling — safer than string concatenation:
Example: os.path Path Handling
import os
# Get current directory
print(os.getcwd()) # /project
# Join paths (automatically handles separators)
path = os.path.join("data", "files", "test.txt")
print(path) # data/files/test.txt
# Check if path exists
print(os.path.exists("test.txt")) # True/False
print(os.path.isfile("test.txt")) # Is it a file?
print(os.path.isdir("data")) # Is it a directory?
# Get file info
print(os.path.getsize("test.txt")) # File size in bytes
# List directory contents
for f in os.listdir("."):
print(f)
Recommended: pathlib (Python 3.4+)
Example: pathlib Path Operations
from pathlib import Path
# Create a path
p = Path("data/files/test.txt")
# Path info
print(p.name) # test.txt (filename)
print(p.stem) # test (without extension)
print(p.suffix) # .txt (extension)
print(p.parent) # data/files (parent directory)
# Read/write file (concise)
p = Path("hello.txt")
p.write_text("Hello, World!", encoding="utf-8")
content = p.read_text(encoding="utf-8")
print(content) # Hello, World!
# Recursive traversal
for py_file in Path(".").rglob("*.py"):
print(py_file)
Tip:
pathlibis the recommended way to handle paths in Python 3.4+. It's more object-oriented and intuitive thanos.path. For new projects, usepathlib.
Common Use Cases
- Data persistence: Save program data to files, restore on next startup.
- Logging: Append program runtime information to log files.
- Configuration management: Read configuration files (
.ini,.json,.env). - Data import/export: Exchange data with Excel/databases using CSV format.
- Batch file processing: Traverse directories, batch modify file content or rename files.
FAQ
encoding="utf-8"?gbk, macOS/Linux uses utf-8. Without specifying, processing Chinese text files on Windows may result in garbled output. Make it a habit to specify encoding for cross-platform peace of mind."w" mode clears existing file content. How do I avoid accidental overwrites?"x" mode (exclusive creation) — if the file already exists, it raises an error instead of clearing it. Or use os.path.exists() to check first. Data is precious — think twice before writing to a file.read() or readlines() — they load the entire file into memory. Use for line in file: to read line by line, processing only one line at a time with minimal memory usage. Alternatively, use read(1024) to read a specific number of bytes at a time.Summary
- File operations in three steps:
open()-> read/write ->close() - The
withstatement manages file closure automatically — the safest approach - Modes:
"r"read,"w"write,"a"append - Reading methods:
read()full content,readlines()as list,for line in fline by line - The
csvmodule for CSV file I/O; supportsDictReader/DictWriter os.pathandpathlibfor file path handling;pathlibis more modern- Always specify
encoding="utf-8"for Chinese text file operations
Exercises
-
Beginner (Difficulty: Star): Write a program that accepts a user's name and age and saves them to a
users.txtfile (one user per line, format:name,age). Append new records each run without overwriting existing data. -
Intermediate (Difficulty: Star-Star): Write a program that reads the
users.txtfile from the previous exercise, parses each line, calculates and outputs the average age of users. Hint: Usesplit(",")to parse,int()to convert age. -
Advanced (Difficulty: Star-Star-Star): Write a "simple notebook" program. Features:
add:title|contentto add a note (append tonotes.csv),listto list all notes,search:keywordto search notes. Store in CSV format (fields: title, content, creation time). Hint: Usedatetime.now()for the current timestamp.



