第十二课:文件操作——让程序记住数据
入门 python教学 · 2026-10-21 · 阅读 3

上一课的"学生成绩小管家"做得挺像样,可它有个大毛病:程序一关,辛辛苦苦录入的成绩全没了,下次打开又得从零录起。这一课给它装上"记忆"——把数据写进文件,关了程序、关了电脑,数据都还在。
一、为什么需要文件
之前我们用的变量,都是把数据存在电脑的内存里,好比记在脑子里:一断电(程序结束),忘得干干净净。而文件是存在硬盘上的,好比记在笔记本上:本子合上,明天翻开还在。
真实软件全是这么干的:微信聊天记录、游戏存档、你打的文档,本质上都是"把数据写进文件"。学会文件操作,你的程序才算从玩具变成工具。
二、写文件:三步走
把一句话存进文件,只需要三步:打开 → 写入 → 关闭。
with open("note.txt", "w", encoding="utf-8") as f:
f.write("今天学会了文件操作!\n")
f.write("程序关掉,数据还在。\n")
运行完,程序目录里会多出一个 note.txt,双击打开就是这两行字。逐个拆解:
| 部分 | 意思 |
|---|---|
| "note.txt" | 文件名。文件会生成在程序所在的文件夹里 |
| "w" | 模式:w 是 write(写入)。文件不存在就新建,存在就清空重写 |
| encoding="utf-8" | 按 utf-8 编码存,中文才不会变乱码。这行别省,省了迟早吃乱码的亏 |
| f.write(...) | 把字符串写进文件。想换行要自己加 \n,程序不会自动帮你换 |
最关键的是开头的 with:它管着这个文件,里面的代码执行完,自动帮你关闭文件。文件开着不关,轻则数据没存全,重则文件损坏。以后写文件,一律用 with 开头,就不用操心关门的事了——好比出门不用记着锁门,门会自己锁。
三、读文件:把数据拿回来
读回来是反过来,把模式换成 "r"(read):
with open("note.txt", "r", encoding="utf-8") as f:
text = f.read()
print(text)
read() 一次性把整个文件读成一个大字符串。还有个常用的 readlines(),按行读成列表,一行一个元素——不过每行末尾都带着换行符 \n,用之前一般要先 strip() 把它削掉,这个坑下一节就会撞上。
再认识一个模式 "a"(append,追加):
| 模式 | 干什么 | 文件已存在时 |
|---|---|---|
| "r" | 读 | 文件不存在会报错 |
| "w" | 写 | 先清空,再写 |
| "a" | 追加写 | 在末尾接着写,不清空 |
记日记、记账本这种"只往后加"的场景就用 "a";要整体重存(比如成绩表),用 "w"。
四、给小管家装上记忆
思路很清晰,就加两个函数:
| 函数 | 职责 |
|---|---|
| load_data() | 程序一启动,从 scores.txt 把成绩读回列表 |
| save_data() | 每次录入后,把整个列表写回 scores.txt |
存的时候要定个格式:一行存一个学生,姓名和成绩用逗号隔开,像这样:
小明,85 小红,92 小刚,78
这种"逗号分隔数据"的存法有个专门的名字叫 CSV,Excel 都能直接打开它,以后还会经常见到。读的时候用 split(",") 把一行拆回姓名和成绩就行。
完整代码(在第十一课的基础上加了两个函数,标★的是新内容):
import os
students = [] # 全班数据:一个装字典的列表
FILENAME = "scores.txt"
def save_data(): # ★ 保存:整个列表写回文件
with open(FILENAME, "w", encoding="utf-8") as f:
for s in students:
f.write(f"{s['姓名']},{s['成绩']}\n")
def load_data(): # ★ 加载:启动时把文件读回列表
if not os.path.exists(FILENAME):
return # 第一次运行,还没有这个文件,很正常
with open(FILENAME, "r", encoding="utf-8") as f:
for line in f:
line = line.strip() # 削掉行尾的换行符
if not line:
continue # 空行跳过
name, score = line.split(",")
students.append({"姓名": name, "成绩": float(score)})
print(f"已从文件读入 {len(students)} 条成绩")
def add_student():
name = input("姓名:")
score = float(input("成绩:"))
students.append({"姓名": name, "成绩": score})
save_data() # ★ 每录入一个就存一次,程序意外关掉也不丢
print("录入成功!")
def show_all():
if not students:
print("还没有数据,先录入吧")
return
for s in students:
print(f"{s['姓名']}:{s['成绩']}分")
def show_avg():
if not students:
print("还没有数据,先录入吧")
return
avg = sum(s["成绩"] for s in students) / len(students)
print(f"全班平均分:{avg:.1f}")
def show_best():
if not students:
print("还没有数据,先录入吧")
return
best = max(students, key=lambda s: s["成绩"])
print(f"最高分:{best['姓名']},{best['成绩']}分")
load_data() # ★ 程序启动先加载旧数据
while True:
print("1.录入成绩 2.查看全部 3.平均分 4.最高分 0.退出")
choice = input("请选择:")
if choice == "1":
add_student()
elif choice == "2":
show_all()
elif choice == "3":
show_avg()
elif choice == "4":
show_best()
elif choice == "0":
print("再见!")
break
else:
print("没有这个选项,重新选吧")
试两遍:第一遍录入两个学生然后退出,去程序目录看看 scores.txt 在不在;第二遍重新运行——"已从文件读入 2 条成绩",选 2 查看,数据原封不动地回来了。这就是"记忆"。
五、文件找不到怎么办
读一个不存在的文件,程序会直接报错崩掉(FileNotFoundError)。上面的 load_data 用 os.path.exists 先问一句"在不在",是办法之一。再教你一个更通用的招——try/except,翻译过来就是"试着干,出错了走这边":
try:
with open("diary.txt", "r", encoding="utf-8") as f:
print(f.read())
except FileNotFoundError:
print("文件还不存在,先写一点内容进去吧")
程序先执行 try 里的代码;一旦报 FileNotFoundError,不崩,转去执行 except 里的代码。这招叫异常处理,以后还会反复见到,这里先混个脸熟。
本课小结
· 变量存内存,关机就忘;文件存硬盘,关机还在。
· 写文件用 with open(...) as f,自动关闭,不怕忘关门。
· 三种常用模式:"r" 读、"w" 清空写、"a" 追加写;中文记得带 encoding="utf-8"。
· 一行一条、逗号分隔,就是 CSV 的存法;读回来用 split 拆开,别忘 strip 削换行符。
· 文件不存在会报错:可以先 exists 判断,也可以用 try/except 兜底。
练一练
1. 通讯录:把 3 个同学的姓名和电话(一行一个,逗号分隔)存进 contacts.txt,再写个程序把它读出来打印。
2. 记账本:用追加模式 "a",每次运行输入一笔消费(比如"奶茶,15")追加进账本,并把全部记录打印出来看看。
3. 挑战题:给小管家加一个功能"5.删除学生":输入姓名,把这个学生从列表里删掉并保存。想想:删完如果不同步保存,会发生什么?
下一课我们把字符串"玩透":切片和各种常用方法——处理文本数据的看家本领。
学·教在线
小ta