文本文件读写:read()、readline()、readlines()、write()、writelines() 方法详解
文本文件读写,是 Python 数据持久化最基础的一环。说白了,就是把内存里的数据存到硬盘上,或者从硬盘里读回来。我刚开始学 Python 时,觉得这玩意儿太简单了,不就是 open 和 close 嘛。直到有一次线上服务因为文件编码问题崩溃……嗯,从那以后我再也不敢小看文件操作了。
今天咱们就把 read()、readline()、readlines()、write()、writelines() 这五个方法彻底讲透。你想想看,掌握了它们,你就能处理 90% 的文本文件场景了。
1. 准备工作:打开文件
在调用任何读写方法之前,你得先拿到一个文件对象。Python 用 open() 函数干这事。我个人习惯用 with 语句,因为它会自动关闭文件,省心。
# 标准写法
with open('example.txt', 'r', encoding='utf-8') as f:
# 在这里读写文件
pass # 文件会自动关闭
encoding='utf-8'。我在项目中遇到过因为系统默认编码不同导致的乱码问题,折腾了半天才发现是编码没指定。
2. 读取方法三兄弟
2.1 read() —— 一口吃成胖子
read() 方法会把整个文件内容读成一个字符串。适合小文件,大文件慎用。
with open('poem.txt', 'r', encoding='utf-8') as f:
content = f.read()
print(content)
# 也可以指定读取的字符数
with open('poem.txt', 'r', encoding='utf-8') as f:
part = f.read(10) # 只读前10个字符
print(part)
read() 会直接撑爆内存。我曾经在生产环境见过有人这么干,结果服务器直接 OOM 了。大文件请用 readline() 或迭代读取。
2.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()
# 更 Pythonic 的写法
with open('log.txt', 'r', encoding='utf-8') as f:
for line in f:
print(line.strip())
你想想看,第二种写法其实底层就是调用了 readline(),但代码简洁多了。我个人更推荐用 for line in f 这种方式。
2.3 readlines() —— 批量读取
readlines() 会把所有行读成一个列表,每行是一个元素。同样适合小文件。
with open('names.txt', 'r', encoding='utf-8') as f:
lines = f.readlines()
print(f"总共有 {len(lines)} 行")
for line in lines:
print(line.strip())
- 文件很小(几 KB):用
read(),简单粗暴 - 文件很大(几百 MB):用
for line in f,内存友好 - 需要随机访问某一行:用
readlines()配合索引
3. 写入方法两兄弟
3.1 write() —— 写字符串
write() 把字符串写入文件。注意它不会自动加换行符,你得自己加 \n。
with open('output.txt', 'w', encoding='utf-8') as f:
f.write('第一行内容\n')
f.write('第二行内容\n')
f.write('第三行内容')
# 追加模式
with open('output.txt', 'a', encoding='utf-8') as f:
f.write('\n这是追加的一行')
\n,结果所有日志都挤在一行里,排查问题的时候眼睛都快看瞎了。所以,写一行记得加换行!
3.2 writelines() —— 写列表
writelines() 接收一个可迭代对象(比如列表),把每个元素写入文件。同样不会自动加换行符。
lines = ['第一行\n', '第二行\n', '第三行\n']
with open('output.txt', 'w', encoding='utf-8') as f:
f.writelines(lines)
# 也可以写生成器表达式
with open('output.txt', 'w', encoding='utf-8') as f:
f.writelines(f'第{i}行\n' for i in range(1, 4))
writelines() 不会在元素之间加任何分隔符。如果你需要换行,请确保每个元素末尾都有 \n。这是新手最容易踩的坑。
4. 实战:日志文件处理
咱们来一个完整的例子。假设你有一个日志文件,需要读取并过滤出错误信息,然后写入新文件。
# 读取原始日志,过滤错误行
with open('app.log', 'r', encoding='utf-8') as f:
error_lines = [line for line in f if 'ERROR' in line]
# 写入错误日志
with open('error.log', 'w', encoding='utf-8') as f:
f.writelines(error_lines)
print(f'共提取 {len(error_lines)} 条错误日志')
这个例子用到了列表推导式 + writelines(),一行代码就完成了过滤和写入。我在项目中经常用这种模式处理日志文件,效率很高。
5. 文件模式速查表
| 模式 | 说明 | 文件存在时 | 文件不存在时 |
|---|---|---|---|
'r' |
只读 | 正常读取 | 报错 FileNotFoundError |
'w' |
只写 | 清空后写入 | 创建新文件 |
'a' |
追加 | 在末尾追加 | 创建新文件 |
'r+' |
读写 | 正常读写 | 报错 |
'w+' |
读写 | 清空后读写 | 创建新文件 |
- 读取用
r,写入用w,追加用a - 小文件用
read()或readlines(),大文件用迭代 - 写入时记得自己加
\n换行 - 永远用
with语句,别手动close() - 指定
encoding='utf-8'避免乱码
好了,这五个方法其实不难,关键是多练。你可以在本地随便建几个文本文件,试试不同的读写组合。嗯,记住一点:文件操作完一定要关闭,用 with 就是最优雅的方式。