7.3 输入输出:文件读写¶
内容梗概¶
本课系统讲解 Python 中的文件读写操作。从 open() 函数的两个核心参数(路径、打开模式)讲起,逐一演示了 r/w/a/x/b/+ 各种模式的含义与区别,强调操作完必须 close()。随后讲解了文本文件的常用方法:read()、readline()、readlines()、write()、tell()、seek(),并解释了文件内部"光标"随读写移动的机制、大文件不能一次性读入内存的问题,以及逐行读取的标准写法。二进制模式和字符编码留到下一节课展开。
知识点详解¶
open() 函数与路径(约 00:01)¶
- Python 的
open()与 C 语言的fopen类似,参数作用都很像。 - 第一个参数是文件的**路径**:如果 .py 文件与目标文件在同一目录,可直接写文件名(即之前讲过的**相对路径**概念)。
- 基本形式:
f = open("log.txt")。
打开模式 mode(约 01:27)¶
- 第二个参数
mode表示打开方式:读取、写入还是追加;默认值是r(读取)。 r= read(读取):只能读,调用write会报错io.UnsupportedOperation: not writable(约 05:00,老师现场演示并强调要会读错误信息)。w= write(写入):只能写,调用read会报not readable(约 05:58);会覆盖/清空文件原有内容(约 06:52)。x= 排他性创建:要求文件**必须之前不存在**,已存在则在open这一行直接报错FileExistsError(约 07:22)。a= append(追加):在原内容末尾追加,不覆盖之前的内容——写日志一般用a(约 08:01)。b= binary(二进制模式)(约 10:30):加在r/w/a后面,如rb、wb,表示以二进制方式读写。硬盘上大部分文件(如 exe)都是二进制的,人类不可直接读;详细内容(字符编码、二进制文件处理)下节课展开。+= 读写兼具(约 11:51):r+可读也可写,在原内容后接着写入;w+会先**清空**文件(与w行为一致),所以打开后立即读到的内容是空的(约 13:09)。
用完必须 close()(约 04:15)¶
- 读或写完成后都要
f.close(),否则文件一直被程序占用——平时"文件被别的程序占用、无法修改/删除"的提示就是这么来的。
read()(约 03:17)¶
f.read()把整个文件内容读入一个字符串;默认r模式下返回字符串。- 可指定长度:
f.read(10)只读 10 个字符(空格等都计入)(约 17:15)。 - 注意大文件问题(约 17:45):文件体积超过内存约两倍时会因内存不足报错(如 8G 内存读 16G 文件);服务器日志文件达到十几 G 很常见,这时必须逐行读。
readline() 与逐行遍历(约 15:51)¶
f.readline()每次读一行,可配合while循环读完全部内容:- 隐藏知识点(约 19:14):文件读完时
read/readline返回空字符串;空字符串在布尔判断中为False,循环自然结束。 - 每行读出的内容**自带换行符
\n**,print又会加一个换行,所以直接打印会出现空行;用刚学过的end=""去掉多余的换行(约 20:15)。
readlines()(约 21:09)¶
f.readlines()一次性把所有行读入,返回一个**列表**:每个元素是文件的一行(字符串),且每行末尾的\n保留。
write()(约 05:00)¶
f.write(字符串)参数是字符串;不会自动换行,要换行需自己写入\n。
文件光标、tell() 与 seek()(约 22:33)¶
- 文件对象内部有一个类似"光标"的位置指示器:每次
read/readline/write后光标自动后移,保证已读内容不重复读、写入内容接着往后写。 f.tell():返回当前光标在文件第几个字符的位置(演示中读一行后tell()返回 14,约 24:26)。f.seek(偏移量):不经过读写、直接移动光标。如f.seek(3)跳过前 3 个字符再读(偏移从 0 开始算,演示中一开始 seek(4) 跳多了,约 26:47)。seek的第二个参数指定偏移基准(约 27:44):默认SEEK_SET(从文件开头算),还有SEEK_END(从文件末尾算)、SEEK_CUR(从当前光标位置算);不展开,鼓励大家自己试——一定要学会自己探索。
示例与演示¶
- 基本读取(约 03:17):
f = open("log.txt")(默认 r 模式)→content = f.read()→print(content),三句话读完全部内容;指出文件本身有空行,输出也有空行;最后f.close()。 - r 模式下 write 报错(约 05:00):尝试
f.write("hello world"),报not writable;现场请同学翻译错误信息,强调读错误信息的习惯。 - w 模式覆盖写入(约 05:58):改成
open("log.txt", "w")后read报not readable;去掉 read 直接write("hello world"),运行无输出,但文件内容被覆盖为 hello world。 - x 模式排他创建(约 07:22):对已存在的文件用
x模式打开,第 1 行 open 处直接报"文件已存在"。 - a 模式追加(约 08:32):
a模式下write("\n")再write("again"),内容追加在原内容之后;换成w则原内容丢失。 - r+ / w+ 对比(约 12:16):
r+先读原内容再写入 hello world,追加在原文之后;w+打开即清空,读出来是空。 - read(10) 限定长度(约 17:15):只读出前 10 个字符。
- 逐行读取大文件(约 18:44):
while+readline循环打印每一行;文件中文显示乱码,老师说明原因下节课讲编码后就会明白,演示时先把中文替换掉。 - readlines 返回列表(约 21:09):打印列表,逐项对应每行,可见每项末尾的
\n。 - tell / seek 定位(约 24:26):读一行后
f.tell()得 14;f.seek(3)跳过开头 3 个字符再读,输出从第 4 个字符开始。
重点与难点¶
- 模式之间的行为差异:
w覆盖清空、a追加、x要求文件不存在、r+/w+读写兼具(w+同样先清空)。 - 务必
close(),否则文件被占用。 read()一次性读入对大文件会因内存不足失败,应逐行(readline)处理。- 文件读完后
read/readline返回空字符串,可作为循环结束条件。 - 每行自带
\n,配合print时注意用end=""避免多余空行;write不会自动换行。 - 易错点:
seek的偏移从 0 开始计数。
关联内容¶
- 前置:相对路径/绝对路径的概念、字符串与布尔逻辑(空字符串为 False)、7.1 节
print的end与file参数(本课直接用end=""解决换行问题)。 - 7.1 节中
print(..., file=f)写日志的演示依赖本课的open/close知识;写日志应使用a追加模式。 - 二进制模式
b、字符编码(为什么中文读出乱码)、BMP 文件头解析等留到下一节课详细展开,并直接与 7.4 的 ASCII 图练习衔接(练习中已用rb读 BMP)。 - 与 C 语言的
fopen对照讲解,帮助有 C 基础的同学迁移。