第 9 章 文件读写与数据格式
学习目标
- 用
open+with读写文本文件 - 掌握追加模式与逐行读取
- 用
csv模块读写表格数据 - 用
json模块读写数据文件
9.1 文本文件读写
文件是保存在磁盘上的数据。Python 用内置函数 open() 打开文件,配合 with 语句使用:
python
with open("test.txt", "w", encoding="utf-8") as f:
f.write("第一行\n第二行\n")open() 的参数:
- 第一个:文件名。
- 第二个:模式。
"w"写入(文件不存在则创建,存在则清空重写),"r"读取(默认),"a"追加(在末尾续写)。 encoding="utf-8"指定编码。中文文件务必带上它,否则可能乱码或报错。
with 的作用是:代码块结束(或出错)时自动关闭文件,不必手动调用 close()。
读取:
python
with open("test.txt", encoding="utf-8") as f:
content = f.read()
print(repr(content))输出:
'第一行\n第二行\n'read() 一次性读出全部内容;repr() 让换行符 \n 显示出来。readlines() 按行读出,得到一个列表,每行带末尾的换行符:
python
with open("test.txt", encoding="utf-8") as f:
lines = f.readlines()
print(lines)输出:
['第一行\n', '第二行\n']追加模式 "a" 在文件末尾续写:
python
with open("test.txt", "a", encoding="utf-8") as f:
f.write("第三行\n")之后文件内容为:
第一行
第二行
第三行9.2 CSV:表格数据
CSV 是「逗号分隔值」的纯文本表格格式,每行是一条记录,列之间用逗号分隔。用标准库 csv 读写:
python
import csv
with open("scores.csv", "w", newline="", encoding="utf-8") as f:
writer = csv.writer(f)
writer.writerow(["姓名", "成绩"])
writer.writerow(["小明", 92])
writer.writerow(["小红", 88])读取:
python
import csv
with open("scores.csv", encoding="utf-8") as f:
for row in csv.reader(f):
print(row)输出:
['姓名', '成绩']
['小明', '92']
['小红', '88']两个要点:
- 写入时
newline=""是 csv 模块的约定写法,避免多余空行。 - CSV 是纯文本,读出来的一切都是字符串:
92变成了'92'。需要计算时用int(row[1])转回数字。
9.3 JSON:数据文件
JSON 是一种与 Python 字典/列表高度对应的数据格式,是程序之间交换数据的通用语言。用 json 模块读写:
python
import json
data = {"name": "小明", "scores": [85, 92]}
with open("data.json", "w", encoding="utf-8") as f:
json.dump(data, f, ensure_ascii=False)
with open("data.json", encoding="utf-8") as f:
loaded = json.load(f)
print(loaded)
print(type(loaded))输出:
{'name': '小明', 'scores': [85, 92]}
<class 'dict'>要点:
json.dump(数据, 文件)把 Python 数据写入文件;ensure_ascii=False让中文以原文保存(否则会写成\u转义)。json.load(文件)把文件内容解析回 Python 的字典 / 列表。- JSON 里字符串必须用双引号,与 Python 的单双引号皆可不同;JSON 数组对应 Python 列表,JSON 对象对应 Python 字典。
文件 data.json 的实际内容:
json
{"name": "小明", "scores": [85, 92]}动手实践
任务一:成绩统计。 把成绩写入 CSV,再读出来计算平均分:
python
import csv
with open("scores.csv", "w", newline="", encoding="utf-8") as f:
writer = csv.writer(f)
writer.writerow(["姓名", "成绩"])
writer.writerow(["小明", 92])
writer.writerow(["小红", 88])
scores = []
with open("scores.csv", encoding="utf-8") as f:
rows = list(csv.reader(f))
for row in rows[1:]:
scores.append(int(row[1]))
print(f"平均分: {sum(scores) / len(scores)}")输出:
平均分: 90.0rows[1:] 跳过表头行。
任务二:通讯录。 把联系人保存为 JSON 文件,再读出来按名字查询:
python
import json
contacts = {"小明": "13800000000", "小红": "13900000000"}
with open("contacts.json", "w", encoding="utf-8") as f:
json.dump(contacts, f, ensure_ascii=False)
with open("contacts.json", encoding="utf-8") as f:
loaded = json.load(f)
print(loaded["小明"])输出:
13800000000常见错误
| 错误写法 | 报错信息 | 原因 |
|---|---|---|
open("nofile.txt") | FileNotFoundError: [Errno 2] No such file or directory: 'nofile.txt' | 读取的文件不存在,先确认路径 |
中文文件不带 encoding | UnicodeDecodeError 或乱码 | 读写中文务必写 encoding="utf-8" |
忘记 with,只 f = open(...) | 不报错但文件句柄泄漏 | 用 with 自动关闭 |
| 用 csv 读出的数字直接计算 | TypeError 或结果错误 | CSV 读出的是字符串,先 int() / float() |
json.loads("{bad json}") | JSONDecodeError: Expecting property name enclosed in double quotes | JSON 格式错误,检查引号是否为双引号 |
章末练习
基础
- 用
"w"模式写入文件poem.txt,内容为两句诗,再读出来打印。 - 用
"a"模式在poem.txt末尾追加一行,重新读取并打印全部内容。 - 把字典
{"name": "小红", "age": 18}保存为user.json,再读出来打印name的值。
提高
- 写程序:读取一个文本文件,统计并输出它的行数、字符数。
- 写程序:把三个人的姓名和成绩写入
scores.csv,再读出来输出成绩最高的那个人的姓名。提示:遍历时记录最大值。
挑战
- 写程序:读入
scores.csv(姓名,成绩两列),输出及格(≥60)人数和不及格人员名单。 - 在
contacts.json基础上改造:程序循环让用户输入姓名,输出对应电话,输入"退出"结束;查不到时提示「未找到」。
章末自测
每题选择一个最佳答案。本书不附答案:完成后交由老师或 AI 老师批改讲解。
- 打开文件用于读取的默认模式是?
- A.
"w" - B.
"r" - C.
"a" - D.
"x"
- A.
- 写入模式
"w"打开已存在文件时,会?- A. 追加内容
- B. 清空后重写
- C. 报错
- D. 只读
with open(...) as f:的好处是?- A. 加快运行速度
- B. 自动关闭文件
- C. 防止乱码
- D. 不需要文件名
- 中文文件读写通常需要指定?
- A.
newline="" - B.
encoding="utf-8" - C.
mode="w" - D.
as f
- A.
csv.reader(f)读出的每个row是?- A. 字符串
- B. 列表
- C. 字典
- D. 元组
- CSV 中读出的数字
92是什么类型?- A. int
- B. str
- C. float
- D. bool
- 把 Python 数据写入 JSON 文件的函数是?
- A.
json.load - B.
json.dump - C.
json.read - D.
json.write
- A.
json.load(f)返回的类型通常是?- A. 字符串
- B. 字典或列表
- C. 文件
- D. 数字
ensure_ascii=False的作用是?- A. 加快写入
- B. 让中文以原文保存
- C. 防止文件覆盖
- D. 自动排序
- 打开不存在的文件用于读取,会报? A.
KeyErrorB.FileNotFoundErrorC.ValueErrorD. 不报错
