文件打开与读取 -- 像打开抽屉看东西
困难3打开文件读内容——就像打开日记本一样简单
你平时写过日记吗?日记本放在抽屉里,想看的时候先拉开抽屉,拿出日记本,翻到那一页,读完之后再放回去、关好抽屉。Python 里的文件操作也是一样的流程:打开文件 → 读取内容 → 关闭文件。学会了这个,你就能用代码读取任何文本文件里的信息——比如全班同学的考试成绩、游戏里的高分记录,甚至是你自己写的班级日志。
1. 用 open() 打开文件
想要读取文件,第一步就是“拉开抽屉”——用 open() 函数。它需要两个“钥匙”:
- 文件名:告诉 Python 是哪个文件(比如
"scores.txt") - 打开模式:告诉 Python 你要做什么。读文件用
"r",是 read 的缩写。
f = open("diary.txt", "r") # 打开一个叫 diary.txt 的文件,准备读取内容
text = f.read() # 读出文件里所有文字
print(text) # 打印到屏幕上看看写了什么
f.close() # 关掉文件,就像把抽屉拉回去
注意:close() 很重要!如果不关,文件可能一直被占用,别的程序就没办法用它了,甚至可能让数据丢失。
2. 更好的方式:用 with 自动关文件
每次都要手动写 close(),万一忘了怎么办呢?Python 有个更省心的写法——with 语句。它就像一个带自动关门功能的抽屉:用完之后,Python 会自动帮你关掉文件,不用你操心。
with open("diary.txt", "r") as f:
text = f.read()
print(text)
# 到这里文件已经自动关闭,不用再写 f.close()
这样代码更短,也绝对不会忘记关文件。以后初学文件操作,推荐你一直用 with 这种写法。
3. 读取全部内容 vs 一行一行读
文件里的内容可以一口气全部读完,也可以按需分段读。想象一下:全班 40 个人的成绩存成一个文件,全部读完可能有点浪费,如果只想看某个人的成绩,一行一行读会更灵活。
| 方法 | 作用 | 适合场景 |
|---|---|---|
read() | 读取整个文件,返回一个字符串 | 文件不大,一次想看完所有内容 |
readline() | 读取当前行的下一行,返回一个字符串 | 只读一行,或按顺序读 |
readlines() | 读取所有行,返回一个列表,每行是一个元素 | 文件行数不多,想用列表处理 |
for line in 文件对象 | 逐行遍历,一行一行读,最省内存 | 文件很大(比如几千行) |
举个例子,假设你有一个 scores.txt 文件,里面是三行考试分数:
85
92
78
方法一:全部读完再用列表处理
with open("scores.txt", "r") as f:
lines = f.readlines() # lines = ['85\n', '92\n', '78\n']
for line in lines:
score = int(line.strip()) # 去掉换行符 \n,再转成整数
print(score) # 依次输出 85, 92, 78
方法二:直接用 for 循环逐行读(推荐)
with open("scores.txt", "r") as f:
for line in f: # Python 会一行一行取,内存里只存一行
score = int(line.strip()) # 去掉末尾的换行符 \n
print(f"第 x 次考试成绩:{score}")
第二种写法不需要先读出全部行再遍历,文件有 10000 行也不怕内存爆掉,所以平时更常用。
4. 处理文件中的数字——小心换行符
从文件读出来的字符串,末尾通常带着一个换行符 \n(就像你在键盘上按了回车)。如果直接转成整数,Python 会报错:
>>> int('85\n')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 10: '85\n'
所以一定要先用 .strip() 去掉两端的空白(包括空格、换行符、Tab 等),再转成数字。上面的例子中已经用了 line.strip(),请记住这个“好习惯”。
如果文件每行除了数字还有其他文字,比如 李小美 85,那就要用 .split() 分割了。这部分我们放到后面“相关指引”里提一下。
5. 新手最容易犯的几个错误
-
错误一:文件不存在时直接报错
如果你用open("不存在.txt", "r"),Python 会生气地报FileNotFoundError。所以一定要确认文件名写对了,文件放在和你的代码同一个文件夹里。如果想更安全,可以用try...except来捕获错误(学到后面会讲)。 -
错误二:忘记调用
close()或忘记写with
如果你只写了f = open(...)却没有f.close(),文件会一直被占用。用with完美解决。 -
错误三:
read()之后还想用readline()
文件对象有一个“指针”,读完之后指针到了末尾,再读就什么都读不到了。如果想重新读,需要先关闭再打开,或者用f.seek(0)把指针移回开头。 -
错误四:把整数和字符串混淆
从文件读取的都是字符串,就算里面写着85,它也是"85"。要算总分就得转成数字。所以记得用int()或float()。
6. 完整可运行示例:读取班级成绩并计算平均分
假设 class_scores.txt 文件内容如下:
李小美 85
王大力 92
赵小雅 78
张明 96
现在写一个程序,读取每个同学的名字和分数,算出平均分,并打印出高于平均分的同学。
# 读取班级成绩,计算平均分并输出高于平均分的学生
total = 0 # 总分初始为0
count = 0 # 人数初始为0
students = [] # 用来存放所有学生名字和分数的列表,每个元素是一个元组
with open("class_scores.txt", "r") as f:
for line in f:
# 去掉换行符,再用空格分割出名字和分数
parts = line.strip().split() # 例如 ["李小美", "85"]
name = parts[0] # 取出名字字符串
score = int(parts[1]) # 取出分数并转成整数
total += score # 累加总分
count += 1 # 人数加1
students.append((name, score)) # 把名字和分数以元组形式加入列表
average = total / count # 计算平均分
print(f"全班平均分:{average:.1f}") # 保留一位小数
print("高于平均分的同学有:")
for name, score in students:
if score > average:
print(f"{name}:{score}分")
运行结果示例:
全班平均分:87.8
高于平均分的同学有:
王大力:92分
张明:96分
这个例子综合了文件读取、字符串处理、循环和数学计算,非常实用。
7. 接下来可以学什么?
- 写入文件:用模式
"w"(write)可以创建或覆盖文件,用"a"(append)可以在末尾追加内容。学完读取,试着写一个自己的日记本程序吧! - 不同编码:如果文件里有中文,读取时可能需要指定编码,比如
open("文件.txt", "r", encoding="utf-8"),不然可能会看到乱码。 - 异常处理:用
try...except可以让程序在文件不存在时给出友好的提示,而不是直接崩溃。 - 处理 CSV 文件:很多表格数据用逗号分隔,学会
split(",")就能轻松解析。
文件操作就像你和计算机之间的“沟通钥匙”——打开了,就能读出里面藏着的所有秘密。多练习几遍,你就能熟练地从各种文本文件中获取信息啦!
例题精讲
在Python中,使用open()函数打开一个已存在的文本文件用于读取内容,应该使用什么模式?
使用open()函数打开文件后,如果不调用close()方法关闭文件,可能导致文件资源泄漏,影响程序稳定性。
以下代码使用with语句打开文件并读取全部内容,请填写缺失的方法名。
with open('data.txt', 'r') as f:
content = f.___()
print(content)在Python中,使用'rb'模式打开一个不存在的文件时,会引发什么异常?
以下代码逐行读取文件并打印每行内容(去掉末尾换行符),请填写合适的表达式。
with open('data.txt', 'r') as f:
for line in f:
print(___)