Python: 文件读写
到目前为止,我们的程序数据只在内存中——程序一关闭,数据就丢了。文件读写让程序能把数据保存到硬盘上,下次启动时再读回来。这是所有实用程序的基础能力。
1. 打开和关闭文件
最基本的文件操作三步:打开 → 读写 → 关闭。
▶ 示例:手动打开和关闭文件
PYTHON
# 写入文件
file = open("hello.txt", "w", encoding="utf-8")
file.write("你好,世界!")
file.close()
# 读取文件
file = open("hello.txt", "r", encoding="utf-8")
content = file.read()
file.close()
print(content) # 你好,世界!
输出:
TEXT
📖 仅展示
# 执行成功
⚠️ 永远记得
close()! 打开的文件会占用系统资源。如果忘记关闭,可能导致文件损坏或资源耗尽。不过别担心——下一节有更好的方法。
2. with 语句(上下文管理器)
with 语句会在代码块结束时自动关闭文件,不用手动调用 close():
▶ 示例:with 语句安全读写
PYTHON
# 写入
with open("hello.txt", "w", encoding="utf-8") as f:
f.write("你好,世界!")
# 读取
with open("hello.txt", "r", encoding="utf-8") as f:
content = f.read()
print(content)
输出:
TEXT
📖 仅展示
# 执行成功
💡 写文件永远用
with 语句。 它是最安全、最 Pythonic 的方式——不管代码块中是否发生异常,文件都会被正确关闭。
3. 文件打开模式
open() 的第二个参数是模式:
| 模式 | 含义 | 文件存在时 | 文件不存在时 |
|---|---|---|---|
"r" |
读取(默认) | 正常读取 | 报错 |
"w" |
写入 | 清空后写入 | 创建 |
"a" |
追加 | 末尾追加 | 创建 |
"x" |
独占创建 | 报错 | 创建 |
"r+" |
读写 | 可读可写 | 报错 |
▶ 示例:不同文件打开模式
PYTHON
# "w" —— 写入(清空重写)
with open("test.txt", "w", encoding="utf-8") as f:
f.write("第一行\n")
f.write("第二行\n")
# "a" —— 追加
with open("test.txt", "a", encoding="utf-8") as f:
f.write("第三行\n")
# "r" —— 读取
with open("test.txt", "r", encoding="utf-8") as f:
print(f.read())
运行结果:
TEXT
📖 仅展示
第一行
第二行
第三行
4. 读取文件的几种方式
▶ 示例:三种文件读取方式
PYTHON
# 先创建测试文件
with open("test.txt", "w", encoding="utf-8") as f:
f.write("第一行\n第二行\n第三行")
# 方式1:read() —— 一次读完
with open("test.txt", "r", encoding="utf-8") as f:
content = f.read()
print(content)
# 方式2:readlines() —— 读成列表
with open("test.txt", "r", encoding="utf-8") as f:
lines = f.readlines()
print(lines) # ['第一行\n', '第二行\n', '第三行\n']
# 方式3:逐行读取(最推荐)
with open("test.txt", "r", encoding="utf-8") as f:
for line in f:
print(line.strip()) # strip() 去掉换行符
输出:
TEXT
📖 仅展示
# 执行成功
▶ 示例:文件备份工具(难度⭐⭐)
PYTHON
def backup_file(filename):
"""创建文件的备份副本"""
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_name}")
except FileNotFoundError:
print(f"文件 {filename} 不存在!")
backup_file("test.txt")
输出:
TEXT
📖 仅展示
# 函数定义成功
5. CSV 文件读写
CSV(逗号分隔值)是最常用的数据交换格式。Python 有内置的 csv 模块:
▶ 示例:CSV 文件读写
PYTHON
import csv
# 写入 CSV
data = [
["姓名", "年龄", "城市"],
["Alice", 25, "北京"],
["Bob", 30, "上海"],
["Charlie", 22, "广州"],
]
with open("students.csv", "w", newline="", encoding="utf-8") as f:
writer = csv.writer(f)
writer.writerows(data)
# 读取 CSV
with open("students.csv", "r", encoding="utf-8") as f:
reader = csv.reader(f)
for row in reader:
print(row)
运行结果:
TEXT
📖 仅展示
['姓名', '年龄', '城市']
['Alice', '25', '北京']
['Bob', '30', '上海']
['Charlie', '22', '广州']
(1) 用字典读写 CSV(更直观)
▶ 示例:DictReader/DictWriter 读写 CSV
PYTHON
import csv
# 写入
data = [
{"name": "Alice", "age": 25, "city": "北京"},
{"name": "Bob", "age": 30, "city": "上海"},
]
with open("students_dict.csv", "w", newline="", encoding="utf-8") as f:
fieldnames = ["name", "age", "city"]
writer = csv.DictWriter(f, fieldnames=fieldnames)
writer.writeheader() # 写表头
writer.writerows(data) # 写数据行
# 读取
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']}岁,来自{row['city']}")
输出:
TEXT
📖 仅展示
# 执行成功
6. 路径处理
用 os.path 或 pathlib 处理文件路径,比直接拼字符串更安全:
▶ 示例:os.path 路径处理
TEXT
📖 仅展示
import os
# 获取当前目录
print(os.getcwd()) # D:\project
# 拼接路径(自动处理分隔符)
path = os.path.join("data", "files", "test.txt")
print(path) # data/files/test.txt
# 检查路径是否存在
print(os.path.exists("test.txt")) # True/False
print(os.path.isfile("test.txt")) # 是不是文件
print(os.path.isdir("data")) # 是不是目录
# 获取文件信息
print(os.path.getsize("test.txt")) # 文件大小(字节)
# 列出目录内容
for f in os.listdir("."):
print(f)
(1) Python 3.4+ 推荐的 pathlib
▶ 示例:pathlib 路径操作
PYTHON
from pathlib import Path
# 创建路径
p = Path("data/files/test.txt")
# 路径信息
print(p.name) # test.txt(文件名)
print(p.stem) # test(无扩展名)
print(p.suffix) # .txt(扩展名)
print(p.parent) # data\files(父目录)
# 读写文件(简洁)
p = Path("hello.txt")
p.write_text("你好,世界!", encoding="utf-8")
content = p.read_text(encoding="utf-8")
print(content) # 你好,世界!
# 递归遍历
for py_file in Path(".").rglob("*.py"):
print(py_file)
输出:
TEXT
📖 仅展示
# 执行成功
💡
pathlib 是 Python 3.4+ 推荐的路径处理方式。 它比 os.path 更面向对象、更直观。新项目建议用 pathlib。
7. 常见应用场景
- 数据持久化:把程序数据保存到文件,下次启动时恢复。
- 日志记录:把程序运行信息追加到日志文件。
- 配置管理:读取配置文件(
.ini、.json、.env)。 - 数据导入导出:用 CSV 格式和 Excel/数据库交换数据。
- 批量文件处理:遍历目录,批量修改文件内容或重命名。
❓ 常见问题
Q
encoding="utf-8" 每次都要写吗?A 在中文环境下,强烈建议每次都写。Python 默认编码因操作系统而异——Windows 是
gbk,macOS/Linux 是 utf-8。如果你不指定,在 Windows 上处理中文文件就可能出现乱码。养成写明编码的习惯,跨平台无忧。Q
"w" 模式会清空已有文件内容,怎么避免误操作?A 用
"x" 模式(独占创建)——如果文件已存在,会报错而不是清空。或者先用 os.path.exists() 检查文件是否存在再决定用什么模式。数据无价,写文件前多考虑一下。Q 文件很大(几百 MB)时怎么读?
A 不要用
read() 或 readlines()——它们会把整个文件加载到内存中。用 for line in file: 逐行读取,每次只处理一行,内存占用很低。或者用 read(1024) 指定每次读取的字节数。📖 小节
- 文件操作三步:
open()→ 读写 →close() with语句自动管理文件关闭,是最安全的做法- 模式:
"r"读取、"w"写入、"a"追加 - 读取方式:
read()全文、readlines()列表、for line in f逐行 csv模块读写 CSV 文件,支持DictReader/DictWriteros.path和pathlib处理文件路径,pathlib更现代- 中文文件操作必须指定
encoding="utf-8"
📝 作业
-
基础题(难度⭐):写一个程序,接收用户输入的名字和年龄,保存到
users.txt文件中(每行一个用户,格式:姓名,年龄)。每次运行追加新记录,不覆盖已有数据。 -
进阶题(难度⭐⭐):写一个程序读取上题生成的
users.txt,解析每行数据,计算并输出用户的平均年龄。提示:用split(",")解析,用int()转年龄。 -
挑战题(难度⭐⭐⭐):写一个"简易笔记本"程序。功能:输入
add:标题|内容添加笔记(追加到notes.csv文件)、输入list列出所有笔记、输入search:关键词搜索笔记。用 CSV 格式存储(字段:标题、内容、创建时间)。提示:用datetime.now()获取当前时间。