Skip to content

第 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']

两个要点:

  1. 写入时 newline="" 是 csv 模块的约定写法,避免多余空行。
  2. 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.0

rows[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'读取的文件不存在,先确认路径
中文文件不带 encodingUnicodeDecodeError 或乱码读写中文务必写 encoding="utf-8"
忘记 with,只 f = open(...)不报错但文件句柄泄漏with 自动关闭
用 csv 读出的数字直接计算TypeError 或结果错误CSV 读出的是字符串,先 int() / float()
json.loads("{bad json}")JSONDecodeError: Expecting property name enclosed in double quotesJSON 格式错误,检查引号是否为双引号

章末练习

基础

  1. "w" 模式写入文件 poem.txt,内容为两句诗,再读出来打印。
  2. "a" 模式在 poem.txt 末尾追加一行,重新读取并打印全部内容。
  3. 把字典 {"name": "小红", "age": 18} 保存为 user.json,再读出来打印 name 的值。

提高

  1. 写程序:读取一个文本文件,统计并输出它的行数、字符数。
  2. 写程序:把三个人的姓名和成绩写入 scores.csv,再读出来输出成绩最高的那个人的姓名。提示:遍历时记录最大值。

挑战

  1. 写程序:读入 scores.csv(姓名,成绩两列),输出及格(≥60)人数和不及格人员名单。
  2. contacts.json 基础上改造:程序循环让用户输入姓名,输出对应电话,输入 "退出" 结束;查不到时提示「未找到」。

章末自测

每题选择一个最佳答案。本书不附答案:完成后交由老师或 AI 老师批改讲解。

  1. 打开文件用于读取的默认模式是?
    • A. "w"
    • B. "r"
    • C. "a"
    • D. "x"
  2. 写入模式 "w" 打开已存在文件时,会?
    • A. 追加内容
    • B. 清空后重写
    • C. 报错
    • D. 只读
  3. with open(...) as f: 的好处是?
    • A. 加快运行速度
    • B. 自动关闭文件
    • C. 防止乱码
    • D. 不需要文件名
  4. 中文文件读写通常需要指定?
    • A. newline=""
    • B. encoding="utf-8"
    • C. mode="w"
    • D. as f
  5. csv.reader(f) 读出的每个 row 是?
    • A. 字符串
    • B. 列表
    • C. 字典
    • D. 元组
  6. CSV 中读出的数字 92 是什么类型?
    • A. int
    • B. str
    • C. float
    • D. bool
  7. 把 Python 数据写入 JSON 文件的函数是?
    • A. json.load
    • B. json.dump
    • C. json.read
    • D. json.write
  8. json.load(f) 返回的类型通常是?
    • A. 字符串
    • B. 字典或列表
    • C. 文件
    • D. 数字
  9. ensure_ascii=False 的作用是?
    • A. 加快写入
    • B. 让中文以原文保存
    • C. 防止文件覆盖
    • D. 自动排序
  10. 打开不存在的文件用于读取,会报? A. KeyError B. FileNotFoundError C. ValueError D. 不报错