本章摘要
- 核心目标:掌握文件读取与写入,让程序的数据能保存到磁盘并重新加载
- 核心知识点:
open()函数、r/w/a三种模式、read/readline/readlines、write/writelines、with上下文管理器、文件路径 - 实操产出:日记本程序,支持写入日记、读取历史记录
- 前置基础:第9-11章函数基础与进阶、第8章字符串操作、第3章异常处理概念
一、写在前面
前面写的程序有一个共同的问题:程序一关,数据全没了。变量、字典、列表里的数据都存在内存中,程序结束就消失。
想让数据"活下来",就需要把它写到文件里。文件存在硬盘上,关机也不会丢。这一章学习 Python 怎么读写文件——从最基础的open()到推荐的with写法,一步步来。
二、打开文件:open()
open()是 Python 内置函数,用来打开文件,返回一个文件对象:
f=open("test.txt","r")# 以只读模式打开content=f.read()# 读取内容print(content)f.close()# 关闭文件(重要!)2.1 文件打开模式
| 模式 | 含义 | 文件不存在时 | 特点 |
|---|---|---|---|
"r" | 只读(默认) | 报错 | 只能读取,不能修改 |
"w" | 只写 | 自动创建 | 覆盖原有内容 |
"a" | 追加 | 自动创建 | 在末尾添加,不覆盖 |
"r+" | 读写 | 报错 | 可读可写 |
最重要的区别:
"w"会清空原文件再写入,"a"不会。新手用"w"时要特别小心,别把重要文件覆盖了。
三、读取文件
3.1read():一次读完
f=open("test.txt","r")content=f.read()# 一次性读取全部内容print(content)f.close()文件很大时不要用
read(),会占用大量内存。
3.2readline():一次读一行
f=open("test.txt","r")line1=f.readline()# 读第一行line2=f.readline()# 读第二行print(line1,end="")# readline 末尾自带换行符,print 的 end="" 避免多空一行print(line2,end="")f.close()3.3readlines():读所有行存列表
f=open("test.txt","r")lines=f.readlines()# 每一行作为列表的一个元素print(lines)# ['第一行\n', '第二行\n', '第三行']f.close()3.4 最推荐:for循环逐行读取
f=open("test.txt","r")forlineinf:# 直接遍历文件对象,一行一行读print(line,end="")# 内存友好,适合大文件f.close()四种读取方式的区别:
read()一次全读、readline()一次一行、readlines()全读存列表、for line in f逐行遍历。日常用for最多。
四、写入文件
4.1write()写入字符串
f=open("diary.txt","w")# "w" 模式:覆盖写入f.write("2026年7月8日\n")f.write("今天学习了文件读写。\n")f.close()4.2writelines()写入多行
lines=["第一行\n","第二行\n","第三行\n"]f=open("notes.txt","w")f.writelines(lines)# 注意:writelines 不会自动加换行符f.close()4.3 追加写入
f=open("diary.txt","a")# "a" 模式:追加写入f.write("追加一段新内容。\n")f.close()
write()和writelines()都不会自动加换行符,需要手动在字符串末尾加\n。
五、with语句:自动关闭文件
每次open()后都要记得close(),忘了关闭可能导致文件损坏或内存泄漏。Python 提供了with语句,自动帮你关闭:
# 传统写法:需要手动 closef=open("test.txt","r")content=f.read()f.close()# with 写法:自动关闭(推荐)withopen("test.txt","r")asf:content=f.read()# 离开 with 块后,文件自动关闭,不用写 close()print(content)with的优势:
- 代码块结束自动关闭文件,不用记
close() - 即使代码出错(如异常),文件也会被正确关闭
- 代码更简洁,缩进清晰
以后写文件读写,一律用
with,忘掉手动close。
六、文件路径
6.1 相对路径与绝对路径
# 相对路径(相对于当前运行目录)withopen("data.txt","r")asf:content=f.read()# 绝对路径(完整路径)# Windowswithopen("C:\\Users\\test\\data.txt","r")asf:content=f.read()# Mac / Linuxwithopen("/home/user/data.txt","r")asf:content=f.read()Windows 路径用反斜杠
\,但 Python 中\是转义字符,所以要写\\(双反斜杠),或者在字符串前加r:r"C:\Users\test\data.txt"。
6.2 推荐:os.path处理路径
importos# 拼接路径(自动适配操作系统)file_path=os.path.join("data","scores.txt")# Windows: data\scores.txt# Mac/Linux: data/scores.txt# 检查文件是否存在ifos.path.exists(file_path):print("文件存在")else:print("文件不存在")七、Scratch 积木对照
本章无 Scratch 对照。Scratch 不涉及文件系统操作,程序数据存在浏览器内存中,关闭即丢失。Python 的文件读写是真正的持久化能力,这是从"玩具程序"到"实用工具"的分水岭。
八、综合实战:日记本程序
综合运用文件读写、with语句、input交互、字符串格式化、函数封装:
# ========================================# 日记本程序# ========================================importos DIARY_FILE="my_diary.txt"defwrite_diary():"""写日记"""date=input("请输入日期(如 2026-07-08):")weather=input("请输入天气:")content=input("请输入日记内容:\n")withopen(DIARY_FILE,"a",encoding="utf-8")asf:f.write(f"{'='*30}\n")f.write(f"日期:{date}\n")f.write(f"天气:{weather}\n")f.write(f"内容:{content}\n")f.write(f"{'='*30}\n\n")print(f"✅ 日记已保存到{DIARY_FILE}")defread_diary():"""读日记"""ifnotos.path.exists(DIARY_FILE):print("📝 还没有日记记录,先写一篇吧!")returnprint(f"\n{'='*30}")print(" 我的日记本")print(f"{'='*30}")withopen(DIARY_FILE,"r",encoding="utf-8")asf:forlineinf:print(line,end="")print(f"\n{'='*30}")defsearch_diary():"""搜索日记"""ifnotos.path.exists(DIARY_FILE):print("📝 还没有日记记录")returnkeyword=input("请输入搜索关键词:")found=Falsewithopen(DIARY_FILE,"r",encoding="utf-8")asf:content=f.read()# 按分隔符拆分每篇日记entries=content.split("="*30)forentryinentries:ifkeywordinentry:print("="*30)print(entry.strip())found=Trueifnotfound:print(f"未找到包含「{keyword}」的日记")# 主程序print("="*30)print(" 日记本 v1.0")print("="*30)whileTrue:print()print("1. 写日记")print("2. 查看所有日记")print("3. 搜索日记")print("4. 退出")print("-"*25)choice=input("请选择(1-4):")ifchoice=="1":write_diary()elifchoice=="2":read_diary()elifchoice=="3":search_diary()elifchoice=="4":print("再见!日记已保存在文件中。")breakelse:print("⚠️ 无效选择")运行效果:
============================== 日记本 v1.0 ============================== 1. 写日记 2. 查看所有日记 3. 搜索日记 4. 退出 ------------------------- 请选择(1-4):1 请输入日期(如 2026-07-08):2026-07-08 请输入天气:晴 请输入日记内容: 今天学会了Python文件读写,很开心! ✅ 日记已保存到 my_diary.txt分步拆解:
- 函数封装:写日记、读日记、搜索日记分别封装成函数,结构清晰
- 追加模式:写日记用
"a"模式,每次新增不会覆盖之前的日记 with语句:所有文件操作用with,自动关闭,不用操心encoding="utf-8":明确指定编码,避免中文乱码os.path.exists:读文件前先检查是否存在,避免FileNotFoundError- 搜索功能:用字符串
split()按分隔符拆分每篇日记,再用in匹配关键词
九、常见报错速查表
| 报错信息 | 出现场景 | 原因 | 解决方法 |
|---|---|---|---|
FileNotFoundError: [Errno 2] | open() | 文件路径不对或文件不存在(r模式) | 检查路径,确认文件存在;或用w/a模式自动创建 |
UnicodeDecodeError | read() | 文件编码与读取编码不一致(常见中文乱码) | open()时加encoding="utf-8" |
PermissionError | open() | 文件被其他程序占用或没有写入权限 | 关闭占用该文件的程序,检查权限 |
io.UnsupportedOperation: not writable | write() | 用 “r” 模式打开却尝试写入 | 改用 “w” 或 “a” 模式打开 |
ValueError: I/O operation on closed file | read/write | 文件已close后还尝试操作 | 把操作放在with块内,或不要提前close |
十、本章小结
本章你掌握了 Python 文件读写的完整流程:
- 打开模式——
r只读、w覆盖写、a追加写,文件不存在时行为不同 - 读取方式——
read()全读、readline()读一行、readlines()读成列表、for line in f逐行遍历 - 写入操作——
write()写字符串、writelines()写多行,都不自动加换行符 with语句——自动关闭文件,即使出错也不漏关,以后一律用with- 文件路径——相对路径/绝对路径,用
os.path处理跨平台路径
文件读写让程序的数据能持久保存,这是从"玩具程序"到"实用工具"的关键一步。
往期回顾:
《Python 零基础入门:从积木到代码》专栏序
零基础学 Python 第1章 | 全平台装环境 + VS Code 配置 + 第一个 Hello World
零基础学 Python 第2章 | print 输出 + 变量赋值 + input 交互输入
零基础学 Python 第3章 | 条件判断:if / elif / else
零基础学 Python 第 4 章 | for 循环与 range():让程序帮你重复干活
零基础学 Python 第 5 章 | while 循环与循环嵌套:让程序看着条件自己干活
零基础学 Python 第 6 章 | 元组与集合:不可变数据与自动去重
零基础学 Python 第7章 | 字典 dict:键值对存储
零基础学 Python 第8章 | 字符串操作与格式化输出
零基础学 Python 第9章 | 函数基础:def、参数与返回值
零基础学 Python 第10章 | 函数进阶:参数灵活用法与作用域
零基础学 Python 第11章 | 匿名函数与高阶函数
下一章预告:文件读写时会遇到各种意外——文件不存在、编码错误、权限不足。下一章学习try-except异常处理,让程序遇到错误不崩溃,而是优雅地处理。
文末资源区
| 资源 | 说明 |
|---|---|
| Python 官方文档 - 文件读写 | https://docs.python.org/3/tutorial/inputoutput.html#reading-and-writing-files |
Python 官方文档 -open() | https://docs.python.org/3/library/functions.html#open |
Python 官方文档 -os.path | https://docs.python.org/3/library/os.path.html |
| 本章完整源码 | chapter12_all.py(关注梅雅达编程笔记,评论领资料) |
每节课都配套课后练习题与完整源码。代码报错、看不懂知识点,可在评论区粘贴问题,逐一解答!
欢迎关注梅雅达编程笔记,持续分享Python零基础学习内容