readlines() 方法主要接受一个可选参数 hint,用于控制读取的行数,从而实现分批读取大文件,以节省内存。

readlines() 方法的基本语法
readlines() 是文件对象的一个方法,其基本语法如下:
file_object.readlines(hint=-1)
file_object: 一个已经打开的文件对象,通常是通过open()函数创建的。hint: 这是一个可选的整数参数,用于提示readlines()最多读取多少字节的数据。
hint 参数详解
hint 参数是 readlines() 方法的关键,它的行为决定了如何读取文件。
不提供 hint 参数(或 hint 为负数,如 -1)
这是最常见的情况。readlines() 会读取文件中所有的行,直到遇到文件结束符 EOF,并将它们作为一个列表返回。
示例:

假设我们有一个名为 my_file.txt 的文件,内容如下:
Hello, World!
This is the second line.
This is the third line.
代码:
# 打开文件
with open('my_file.txt', 'r') as f:
# 不提供 hint 参数,读取所有行
all_lines = f.readlines()
# 打印结果
print(all_lines)
# 输出: ['Hello, World!\n', 'This is the second line.\n', 'This is the third line.\n']
# 遍历每一行
for line in all_lines:
print(line.strip()) # 使用 strip() 去除末尾的换行符 \n
输出:
Hello, World!
This is the second line.
This is the third line.
⚠️ 重要警告:内存消耗
如果文件非常大(比如几十GB),使用不带 hint 的 readlines() 会一次性将整个文件加载到内存中,很可能导致内存溢出(MemoryError),使程序崩溃。

hint 为一个正整数
当提供一个正整数 hint 时,readlines() 的行为会变得复杂一些,但核心目标是读取大约 hint 字节的数据。
工作原理:
readlines()开始从文件当前位置读取数据。- 它会持续读取,直到累计读取的字节数至少达到
hint。 - 为了保证返回的每一行都是完整的,它会继续读取,直到找到一个完整的换行符
\n。 - 返回的列表中包含在
hint提示点之后遇到的第一个完整换行符之前的所有行。
返回的行数不固定,但返回的数据量会大致接近 hint 字节,这对于逐块处理大文件非常有用。
示例:
我们仍然使用上面的 my_file.txt 文件,假设我们希望每次读取大约 20 个字节。
代码:
# 打开文件
with open('my_file.txt', 'r') as f:
# 第一次读取,hint=20
chunk1 = f.readlines(20)
print(f"第一次读取 (hint=20): {chunk1}")
# 输出: 第一次读取 (hint=20): ['Hello, World!\n']
# 第二次读取,hint=20
chunk2 = f.readlines(20)
print(f"第二次读取 (hint=20): {chunk2}")
# 输出: 第二次读取 (hint=20): ['This is the second line.\n']
# 第三次读取,hint=20
chunk3 = f.readlines(20)
print(f"第三次读取 (hint=20): {chunk3}")
# 输出: 第三次读取 (hint=20): ['This is the third line.\n']
# 第四次读取,文件已读完
chunk4 = f.readlines(20)
print(f"第四次读取 (hint=20): {chunk4}")
# 输出: 第四次读取 (hint=20): []
分析:
f.readlines(20)尝试读取 20 字节,它读取了"Hello, World!\n"(15个字符,在UTF-8编码下通常是15个字节),这已经超过了20字节的提示,并且遇到了一个完整的换行符,所以返回这一行。- 再次调用时,它从下一行开始,读取了
"This is the second line.\n"(26个字符),也超过了提示,并返回这一行。 - 依此类推。
readlines() 与 for line in f 的对比
在 Python 中,逐行读取文件最推荐、最 Pythonic 的方式是使用 for 循环直接遍历文件对象。
# 推荐方式
with open('my_file.txt', 'r') as f:
for line in f:
print(line.strip())
这种方式和 readlines() 有什么区别?
| 特性 | for line in f (迭代器方式) |
f.readlines() (列表方式) |
|---|---|---|
| 内存效率 | 极高,每次只从文件中读取一行到内存,处理完后就丢弃,非常适合大文件。 | 较低,一次性将所有行(或 hint 指定的大块数据)加载到内存中。 |
| 代码简洁性 | 非常简洁,代码意图清晰,无需手动管理列表。 | 稍显冗长,需要创建一个列表变量。 |
| 性能 | 对于大文件,由于避免了一次性加载,性能和内存占用都更优。 | 对于小文件,一次性读取可能比逐行迭代稍快,因为减少了I/O操作次数。 |
| 灵活性 | 只能顺序读取,无法回头。 | 返回一个列表,可以方便地通过索引访问任意一行(如 lines[5]),可以多次遍历。 |
- 处理大文件:永远优先选择
for line in f,这是最安全、最节省内存的方式。 - 处理小文件或需要随机访问行时:可以使用
readlines(),你可能想把所有行读入一个列表,然后对它们进行排序或随机访问。
| 参数 | 行为 | 适用场景 |
|---|---|---|
无参数或 hint=-1 |
读取文件所有行到内存中的一个列表。 | 处理小文件,或者你需要一次性获取所有内容并多次访问。 |
hint=N (N为正整数) |
尝试读取大约 N 字节的数据,并返回完整的行列表,用于分批读取大文件。 |
在内存非常有限的情况下,需要手动分块处理超大文件,通常 for line in f 是更好的替代方案。 |
最佳实践建议:
在绝大多数情况下,特别是处理未知大小的文件时,请使用 for line in file_object: 的方式来逐行读取,这是 Python 社区公认的最佳实践。
