文本文件读写:read()、readline()、readlines()、write()、writelines() 方法详解
文件读写,说白了就是让程序和硬盘上的文件「对话」。我刚开始学 Python 时,总觉得这步很简单——不就是打开、读写、关闭嘛。但真正做项目后才发现,选对方法比会写代码重要得多。
今天咱们就一口气把 Python 文本文件读写的五个核心方法讲透。嗯,我会结合自己踩过的坑来讲,你听完就能直接用。
一、先搭个架子:文件打开与关闭
在讲具体方法前,我得先提一句:所有读写操作都建立在文件对象上。你想想看,就像你要从书架上拿书,总得先知道书在哪吧?
# 标准写法
f = open('data.txt', 'r', encoding='utf-8')
content = f.read()
f.close()
我个人习惯用 with 语句,它自动帮你关闭文件,省心不少:
with open('data.txt', 'r', encoding='utf-8') as f:
content = f.read()
# 出了这个缩进,文件自动关闭
小提示: 记得指定
encoding='utf-8'。我遇到过好几次因为编码问题导致乱码的尴尬,尤其是 Windows 系统默认编码是 gbk,很容易踩坑。
二、读取三兄弟:read()、readline()、readlines()
这三个方法都是用来读文件的,但用法和场景完全不同。咱们一个一个看。
1. read() —— 一口气读完
read() 会把整个文件内容当作一个字符串返回。简单粗暴,适合小文件。
with open('poem.txt', 'r', encoding='utf-8') as f:
data = f.read()
print(data)
print(f'一共读取了 {len(data)} 个字符')
你也可以指定读取的字符数:
with open('poem.txt', 'r', encoding='utf-8') as f:
chunk = f.read(100) # 只读前100个字符
print(chunk)
注意: 如果文件很大(比如几百 MB),用
read() 会一次性把内容全加载到内存里。我曾经在分析日志文件时这么干过,结果程序直接卡死……后来改用逐行读取了。
2. readline() —— 读一行
readline() 每次只读一行,包括行尾的换行符 \n。适合逐行处理大文件。
with open('log.txt', 'r', encoding='utf-8') as f:
line = f.readline()
while line:
print(line.strip()) # strip() 去掉换行符
line = f.readline()
你想想看,如果日志文件有 10 万行,用 read() 直接爆炸,但 readline() 就能优雅地一行一行处理。
3. readlines() —— 读所有行
readlines() 会把文件所有行读到一个列表里,每行是一个元素(包含换行符)。
with open('students.txt', 'r', encoding='utf-8') as f:
lines = f.readlines()
for i, line in enumerate(lines, 1):
print(f'第{i}行: {line.strip()}')
不过要注意,readlines() 也是全量加载,大文件慎用。
| 方法 | 返回值 | 适用场景 | 内存占用 |
|---|---|---|---|
| read() | 字符串 | 小文件、需要全文处理 | 高(全量加载) |
| readline() | 字符串(单行) | 大文件逐行处理 | 低(一次一行) |
| readlines() | 列表(每行一个元素) | 中等文件、需要随机访问行 | 高(全量加载) |
我的建议: 如果文件小于 10 MB,用
read() 或 readlines() 都行。如果文件更大,老老实实用 readline() 或者直接 for line in f: 迭代读取。
三、写入双雄:write() 和 writelines()
写文件也有两个方法,但很多人容易搞混。我刚开始也犯过这种错。
1. write() —— 写一个字符串
write() 把字符串写入文件,不会自动加换行符。
with open('output.txt', 'w', encoding='utf-8') as f:
f.write('第一行内容')
f.write('第二行内容') # 注意:这行会紧跟在第一行后面
如果你想要换行,得自己加 \n:
with open('output.txt', 'w', encoding='utf-8') as f:
f.write('第一行内容\n')
f.write('第二行内容\n')
2. writelines() —— 写一个列表
writelines() 接收一个可迭代对象(比如列表),把每个元素写入文件。注意:它也不会自动加换行符。
lines = ['第一行\n', '第二行\n', '第三行\n']
with open('output.txt', 'w', encoding='utf-8') as f:
f.writelines(lines)
我曾经踩过的坑: 刚开始我以为
writelines() 会自动加换行,结果写出来的文件所有内容挤在一行。后来才明白,它只是把列表里的字符串「拼」在一起写进去,换行符得你自己加。
四、核心知识体系
下面这张图帮你理清这五个方法的关系:
五、实战:一个完整的读写示例
咱们写个小程序,把学生成绩写入文件,再读出来统计平均分。这样你就能看到这些方法怎么配合使用了。
# 写入成绩
students = [
'张三,85\n',
'李四,92\n',
'王五,78\n',
'赵六,95\n'
]
with open('scores.txt', 'w', encoding='utf-8') as f:
f.writelines(students)
print('成绩写入完成')
# 读取并统计
total = 0
count = 0
with open('scores.txt', 'r', encoding='utf-8') as f:
for line in f: # 直接用迭代,底层就是 readline()
name, score = line.strip().split(',')
total += int(score)
count += 1
avg = total / count
print(f'共 {count} 名学生,平均分: {avg:.1f}')
小技巧: 用
for line in f: 逐行读取,既简洁又高效。它底层调用的就是 readline(),但代码写起来更优雅。
六、避坑指南
最后分享几个我亲身踩过的坑,你遇到了能少走弯路:
- 忘记加换行符: 写文件时,
write()和writelines()都不会自动加\n。我刚开始写日志文件时,所有内容都挤在一行,排查了半天才发现。 - 大文件用 read(): 有一次处理 2 GB 的日志文件,用
read()直接内存溢出。后来改成逐行读取才搞定。 - 编码问题: 读 Windows 下生成的文件,如果不指定
encoding='utf-8',可能会报错或乱码。我建议统一用 UTF-8。 - 文件模式搞混:
'w'会覆盖原文件,'a'是追加。我曾在生产环境用'w'覆盖了重要数据……嗯,从那以后我每次写文件前都再三确认模式。
好了,这五个方法其实不难,关键是多练、多踩坑。你把这些代码自己跑一遍,很快就能掌握。