第 0 步 · 程序为什么会"忘记"
到目前为止,你写的程序一退出,数据就没了(变量在内存里)。文件 = 磁盘上的持久存储。学会读写文件,程序才真正"办事":日志、配置、数据存档、批处理……
第 1 步 · 读文件
1.1 最基础写法(三步:打开→读→关闭)
f = open("data.txt", "r") # r = read 只读模式
content = f.read() # 整个文件读成一个字符串
f.close() # 关闭(忘了关会占用句柄)
1.2 推荐写法:with 自动关闭(永远用这个)
with open("data.txt", "r", encoding="utf-8") as f:
content = f.read() # with 块结束自动 close,不怕忘
# 读成行列表:
with open("data.txt", "r", encoding="utf-8") as f:
lines = f.readlines() # ['第一行\n', '第二行\n', ...]
encoding="utf-8" 必须养成习惯:Windows 默认用 gbk 读文件,中文字符会乱码或报 UnicodeDecodeError。写上 utf-8 到处都能跑。
第 2 步 · 写文件
with open("out.txt", "w", encoding="utf-8") as f:
f.write("第一行\n") # \n 是换行符
f.write("第二行\n")
# 追加模式(不清空原内容)
with open("log.txt", "a", encoding="utf-8") as f:
f.write("2026-08-12 新纪录\n")
模式速查:
"r" 读(文件不存在 → FileNotFoundError);"w" 写(存在则清空重写!);"a" 追加;"x" 新建(已存在报错,防覆盖)。第 3 步 · 异常处理(try/except)
文件会不存在、用户会输错、网络会断。异常处理 = 给程序穿防弹衣。
3.1 基本结构
try:
with open("no_such.txt", "r") as f:
content = f.read()
except FileNotFoundError:
print("文件不存在,先创建它")
except Exception as e: # 兜底:任何异常都接住
print("出错了:", e)
3.2 完整结构:try / except / else / finally
try:
num = int(input("数字:"))
except ValueError:
print("这不是数字")
else:
print(f"你输入了 {num}") # 没异常才执行
finally:
print("无论如何都会执行") # 清理资源用
别用裸 except: 什么都不写会吞掉所有错误(包括你没想到的),难排查。精确捕获(ValueError、FileNotFoundError…)才是专业做法;兜底用
except Exception 并打印信息。第 4 步 · JSON(程序间的通用语言)
JSON 是 Web/API/配置的事实标准格式,长得像 Python 字典:
4.1 写入(dump)
import json
student = {"name": "丢丢", "age": 6, "scores": {"数学": 92, "英语": 88}}
with open("student.json", "w", encoding="utf-8") as f:
json.dump(student, f, ensure_ascii=False, indent=2)
# ensure_ascii=False:中文原样保存(否则变成 \uXXXX)
4.2 读取(load)
with open("student.json", "r", encoding="utf-8") as f:
data = json.load(f)
print(data["name"], data["scores"]["数学"]) # 丢丢 92
JSON 与字典的区别:JSON 是文本(文件里是字符串);Python 字典是内存对象。
dump/load 负责在两者间转换。以后调 API(⑧)返回的就是 JSON 文本。第 5 步 · 路径(文件在哪里)
import os
os.getcwd() # 当前工作目录
os.path.exists("data.txt") # True/False 文件是否存在
os.path.join("data", "raw", "a.txt") # 跨平台拼路径
os.makedirs("data/raw", exist_ok=True) # 建目录(存在也不报错)
路径口诀:相对路径是"从程序当前目录出发";写脚本时用
os.path.join 而不是手拼 "data/raw"(Windows 用反斜杠会炸)。更现代的 pathlib 节点 ⑥ 再学。第 6 步 · 实战项目:成绩存档程序
需求:一个命令行程序——输入学生与多科成绩,可保存、可查看、可追加,数据用 JSON 持久化。这就是"最小可用的数据管理程序"。
Step 1:核心函数库(保存 + 读取 + 加成绩)
# grade_book.py
import json, os
FILE = "grades.json"
def load_grades():
"""读取成绩,文件不存在返回空字典"""
if not os.path.exists(FILE):
return {}
with open(FILE, "r", encoding="utf-8") as f:
return json.load(f)
def save_grades(grades):
with open(FILE, "w", encoding="utf-8") as f:
json.dump(grades, f, ensure_ascii=False, indent=2)
Step 2:主程序(命令循环 + 异常兜底)
# main.py
import grade_book
grades = grade_book.load_grades()
while True:
cmd = input("命令(add/see/quit):").strip().lower()
if cmd == "quit":
break
elif cmd == "add":
name = input("学生名:")
subject = input("科目:")
try:
score = float(input("分数:"))
except ValueError:
print("分数无效,未保存")
continue
grades.setdefault(name, {})[subject] = score
grade_book.save_grades(grades)
print("已保存")
elif cmd == "see":
for name, subs in grades.items():
print(name, subs)
else:
print("未知命令")
这个程序的意义:它第一次实现了"数据进出磁盘"。以后任何项目(背单词、记账、番茄统计)都是这个骨架:数据结构 + 文件读写 + 命令循环。跑通它,你的脚本就能在服务器上长期运行了。
第 7 步 · 报错手册(本节点新增)
1. FileNotFoundError —— 读的文件不存在。修法:先
os.path.exists() 判断,或 try/except。2. UnicodeDecodeError —— 文件编码不是 utf-8。修法:open 时指定
encoding="utf-8";老文件试 encoding="gbk"。3. json.JSONDecodeError —— JSON 文件内容损坏(比如手动编辑弄坏括号)。修法:备份后检查文件;读的时候 try/except 兜底。
4. PermissionError —— 没权限读写(文件被占用/目录只读)。修法:检查文件是否被别的程序打开、路径权限。
节点自测清单
- 徒手写出:with open 读文件并按行处理
- 徒手写出:try/except 处理用户输入非数字
- 能说清 "r" / "w" / "a" 三种模式的区别与危险点
- 徒手写出:字典 → JSON 文件 → 读回来
- 能独立完成成绩存档程序(含异常兜底)
- 知道 ensure_ascii=False 和 encoding="utf-8" 什么时候用
全勾 → 节点 ④ 完成,进入节点 ⑤(面向对象入门)。未勾 → 回看对应步骤。