嗨,小伙伴们!欢迎回来!
在上节课,我们学会了用函数这个“魔法盒子”把代码打包,让程序变得井井有条。但是,不知道你有没有发现一个问题:我们之前写的程序,比如那个“学生成绩计算器”,一旦关闭运行窗口,所有学生的成绩就消失了,下次启动又得重新输入。这就像一条只有7秒记忆的鱼,是不是很可惜?
想象一下,你玩一款超好玩的游戏,每次退出后进度都归零,你愿意吗?肯定不愿意!程序也需要能“记住”东西的能力。今天,我们就来学习如何给Python程序装上“记忆硬盘”——文件操作。学完这节课,你的程序就能把数据保存到文件里,下次启动时再读出来,实现真正的“记忆”功能!
一、为什么程序需要读写文件?
我们之前的数据都存储在内存里,它的特点是速度快,但断电即失(程序关闭后数据就没了)。而硬盘上的文件,比如你电脑里的TXT、Excel,可以长久保存。
文件操作,就是搭建起“内存”与“硬盘”之间的桥梁。它让你的程序能够:
长久保存数据:用户配置、游戏存档、计算结果,下次打开还在。
处理大量数据:从文件中读取成千上万条记录进行分析。
与其他程序交换数据:你的Python程序可以读取Excel文件,或者生成日志文件供其他工具分析。
二、打开文件:先找到你的“记忆笔记本”
要读写文件,第一步就是打开它。Python用内置的 open() 函数来做这件事,就像你从书包里拿出一个笔记本。
python
# 语法:文件对象 = open(文件路径, 打开模式)file=open('notes.txt','r')# 以只读模式打开当前目录下的 notes.txt 文件文件路径:告诉Python去哪里找文件。'notes.txt' 表示当前程序所在的目录。
打开模式:决定了你要对文件做什么。最常用的有这几种:
| | | |
|---|
'r' | | | |
'w' | | | 如果文件存在,会清空原有内容 |
'a' | | | 文件不存在会创建新文件;存在则在末尾添加,不会清空原有内容。 |
'x' | | | |
💡 小贴士:对于文本文件,通常还会加上 't',比如 'rt' 或 'wt',但 't' 是默认的,所以可以省略不写。如果要处理图片、视频等二进制文件,则需要用 'b' 模式(如 'rb')。
三、读取文件:看看笔记本里记了什么
打开文件后,我们就可以用各种方法“阅读”它了。假设我们有一个 poem.txt 文件,内容如下:
text
床前明月光,疑是地上霜。举头望明月,低头思故乡。
3.1 读取全部内容:read()
用 .read() 方法,就像一口气把整本笔记本读完。
python
file=open('poem.txt','r', encoding='utf-8')# 注意:中文文件通常要指定编码content =file.read()print(content)file.close()# 重要!用完要关闭# 输出:# 床前明月光,# 疑是地上霜。# 举头望明月,# 低头思故乡。⚠️ 特别注意:操作完文件后,一定要调用 close() 关闭它。这就像看完书要合上一样,既能释放系统资源,也能确保数据完整。如果忘记关闭,可能会导致数据丢失或程序出错。
3.2 逐行读取:readline() 和 readlines()
对于大文件,一次性读取可能占用太多内存。逐行读取是更好的方式。
readline():每次读取一行。
python
file=open('poem.txt','r', encoding='utf-8')line1 =file.readline()# 读取第一行:'床前明月光,\n'line2 =file.readline()# 读取第二行:'疑是地上霜。\n'print(line1, end='')# 用 end='' 去掉 print 自带的换行,因为 line1 本身就有换行符print(line2, end='')file.close()readlines():读取所有行,并以列表形式返回,每一行是列表的一个元素。
python
file=open('poem.txt','r', encoding='utf-8')lines =file.readlines()print(lines)file.close()# 输出:['床前明月光,\n', '疑是地上霜。\n', '举头望明月,\n', '低头思故乡。']
3.3 最优雅的方式:直接用 for 循环遍历文件对象
这是Python中读取文件最推荐、最Pythonic的方式!文件对象本身就是一个迭代器,可以直接在 for 循环中使用,每次迭代得到一行。而且,这种方法在处理大文件时内存效率最高。
python
file=open('poem.txt','r', encoding='utf-8')for line infile:print(line, end='')# 逐行打印file.close()四、写入文件:在笔记本上记新东西
写入文件同样简单,但要注意模式的选择。
4.1 写入模式 ('w'):清空重写
这相当于你拿了个新笔记本,或者把旧笔记本的内容全部擦掉,开始写新的。
python
file=open('diary.txt','w', encoding='utf-8')file.write('2026年3月2日,天气晴\n')file.write('今天学会了Python文件操作,感觉超棒!\n')file.write('明天继续加油!\n')file.close()# 运行后,diary.txt 文件里就只有这三行内容。4.2 追加模式 ('a'):在末尾续写
这相当于你在笔记本已有的内容后面,接着写新的日记。
python
file=open('diary.txt','a', encoding='utf-8')file.write('2026年3月3日,补充一句:文件操作真的太有用了!\n')file.close()# 现在 diary.txt 的内容是在原来的三行后面,新增了第四行。注意:write() 方法不会自动换行,需要你自己加上 \n。
五、终极懒人包:with 语句(自动关闭文件)
每次都手动 close() 文件,不仅麻烦,还可能因为程序中途出错而忘记关闭。Python提供了一个非常优雅的解决方案——with 语句。它会在代码块执行完毕后,自动帮你关闭文件,即使发生异常也不例外。
这就是文件操作的“懒人神器”,也是最标准的写法!
python
# 读取文件withopen('poem.txt','r', encoding='utf-8')asfile: content =file.read()print(content)# 这里不用写 file.close(),with 语句已经自动处理了# 写入文件withopen('diary.txt','a', encoding='utf-8')asfile:file.write('这是用 with 语句追加的一行,安全又省心!\n')有了 with,代码更简洁,也更安全。从现在开始,请养成使用 with open(...) as ... 的好习惯!
六、综合案例:给“学生成绩计算器”装上记忆
还记得上节课的成绩计算器吗?数据都是写死在代码里的。现在,我们让它从文件读取学生信息,并把报告也保存到文件里。
第一步:准备数据文件 students.csv
在你的Python程序同目录下,新建一个文本文件,命名为 students.csv(CSV是一种常见的数据交换格式,用逗号分隔值),内容如下:
text
小明,85,92,78小红,90,88,95小刚,78,85,82小丽,92,96,89
第二步:编写带文件读写功能的成绩报告程序
python
defget_grade(score):"""根据分数返回等级"""if score >=90:return"A"elif score >=80:return"B"elif score >=70:return"C"elif score >=60:return"D"else:return"F"defaverage(scores):"""计算平均分"""returnsum(scores)/len(scores)defread_students_from_file(filename):"""从CSV文件读取学生数据,返回一个字典""" students ={}try:withopen(filename,'r', encoding='utf-8')as f:for line in f:# 去掉行尾的换行符,然后按逗号分割 parts = line.strip().split(',')iflen(parts)==4:# 确保格式正确 name = parts[0]# 将分数从字符串转为整数 scores =[int(parts[1]),int(parts[2]),int(parts[3])] students[name]= scoresprint(f"成功从 {filename} 加载了 {len(students)} 位学生的数据。")except FileNotFoundError:print(f"错误:文件 {filename} 未找到,请检查文件路径。")except Exception as e:print(f"读取文件时发生未知错误:{e}")return studentsdefgenerate_report(students, output_filename):"""生成成绩报告,并写入文件""" total_scores =[] report_lines =[]# 用于收集要写入文件的内容# 准备报告标题 header ="="*40 title ="班级成绩报告" report_lines.append(header) report_lines.append(title) report_lines.append(header)for name, scores in students.items():# 生成单个学生报告行 avg_score = average(scores) line =(f"学生:{name} | 语文:{scores[0]}({get_grade(scores[0])}) "f"数学:{scores[1]}({get_grade(scores[1])}) "f"英语:{scores[2]}({get_grade(scores[2])}) | "f"平均分:{avg_score:.1f}({get_grade(avg_score)})") report_lines.append(line) total_scores.extend(scores)# 准备班级平均分行 report_lines.append("-"*40) class_avg = average(total_scores) report_lines.append(f"全班平均分:{class_avg:.1f} ({get_grade(class_avg)})")# 将报告打印到屏幕for line in report_lines:print(line)# 将报告写入文件try:withopen(output_filename,'w', encoding='utf-8')as f:for line in report_lines: f.write(line +'\n')print(f"\n报告已成功保存到文件:{output_filename}")except Exception as e:print(f"写入文件时出错:{e}")# --- 主程序部分 ---input_file ='students.csv'output_file ='class_report.txt'# 1. 从文件读取数据student_data = read_students_from_file(input_file)# 2. 如果成功读取到数据,则生成报告if student_data: generate_report(student_data, output_file)else:print("程序终止,因为没有加载到学生数据。")运行这个程序,你会发现:
控制台打印出了漂亮的成绩报告。
程序目录下新生成了一个 class_report.txt 文件,里面的内容和控制台输出一模一样。
现在,你的程序终于拥有“记忆”了!想换一批学生?直接修改 students.csv 文件就行,完全不用改动代码。这就是数据与逻辑分离的巨大好处。
七、新手避坑指南
7.1 常见错误及解决方法
| | |
|---|
| 文件找不到 | FileNotFoundError | 1. 检查文件名和路径是否正确。2. 确保文件确实存在于那个位置。3. 对于 'r' 模式,文件必须存在。 |
| 编码问题 | UnicodeDecodeError | 打开文件时,始终指定 encoding='utf-8',这是最通用的编码。 |
| 忘记关闭文件 | | 养成习惯,要么手动 close(),最好使用 with 语句自动管理。 |
| 意外覆盖文件 | | 使用 'x' 模式可以安全地创建新文件,如果文件存在会报错。或者先检查文件是否存在。 |
| 写入后没换行 | | 在 write() 的内容末尾手动加上换行符 \n。 |
7.2 三个实用小贴士
善用 try...except 处理文件异常:文件操作(比如读取一个不存在的文件)很容易出错。用 try...except 捕获错误,并给用户友好的提示,而不是让程序直接崩溃。上面的综合案例就是一个很好的示范。
处理路径用 pathlib:对于复杂的文件路径操作(比如拼接路径、获取文件名),Python的 pathlib 库非常方便。不过那是进阶内容,现在先确保能读写同目录下的文件就好。
'w' 和 'a' 的抉择:不确定时问自己:“我是要重写整个笔记本,还是只在末尾加新笔记?” 要清空旧内容,用 'w';要保留旧内容并追加,用 'a'。
八、总结与下一步
恭喜你!今天你给Python程序装上了至关重要的“记忆硬盘”。现在你掌握了:
✅ 文件打开三要素:open() 函数、文件路径、打开模式(r, w, a)
✅ 读取文件的多种方式:read()、readline()、readlines(),以及最优雅的 for line in file
✅ 写入文件:用 write() 配合 'w' 或 'a' 模式
✅ 终极安全写法:用 with open(...) as file: 自动管理文件关闭
✅ 综合运用:从文件读取数据,并将处理结果写回文件,让程序拥有“记忆”
文件操作是连接程序和外部世界的桥梁。有了它,你的程序才真正具备了实用性。
下一步,我们将探索如何让程序更好地应对运行中的意外情况,学习 “异常处理”——当程序遇到错误时,如何优雅地处理,而不是直接崩溃。这样,你的程序会变得更加健壮和专业!
还是那句话:编程不是看会的,而是练会的。快打开你的Python环境,把文中的例子亲手敲一遍。试着修改 students.csv 的内容,或者在 generate_report 函数里增加新的统计项,看看会发生什么。有任何问题,欢迎在评论区留言交流!
下期预告:Python异常处理:如何让你的程序在“翻车”时也能优雅收场?敬请期待!