在 Python 中,按行读取文件是最常见的操作之一。readline() 和 readlines() 是两个用于逐行读取的文件对象方法。理解它们的区别和适用场景,可以帮助你高效、安全地处理各种大小的文件。
一、readline() 方法
语法
参数
返回值
特点
每次调用读取一行(包括换行符 \n)。
自动处理不同的换行符(\n, \r\n, \r),统一返回 \n 结尾的字符串(取决于 newline 参数)。
如果不指定 size,读取整行;如果指定 size,可能只读取该行的一部分。
示例1:基本使用
with open('data.txt', 'r', encoding='utf-8') as f: line1 = f.readline() # 读取第一行 line2 = f.readline() # 读取第二行 print(repr(line1)) print(repr(line2))
示例2:循环读取所有行
with open('data.txt', 'r', encoding='utf-8') as f: line = f.readline() while line: print(line.strip()) # strip() 去掉末尾换行符 line = f.readline()
示例3:指定 size 参数
withopen('data.txt', 'r') as f: partial = f.readline(5) # 最多读取5个字符,但仍会停在行尾 print(partial)
二、readlines() 方法
语法
参数
返回值
特点
示例1:基本使用
with open('data.txt', 'r', encoding='utf-8') as f: lines = f.readlines() for i, line in enumerate(lines, 1): print(f"{i}: {line.strip()}")
示例2:使用 hint 参数限制内存
with open('large.log', 'r') as f: # 每次读取大约 8192 字节的数据,但只返回完整的行 while True: lines = f.readlines(8192) if not lines: break for line in lines: process(line)
三、readline() vs readlines() 对比
何时使用 readline()?
处理大文件(例如数百 MB 或 GB)
只需要逐行处理,不需要再次访问之前的行
想要更精细地控制读取过程
何时使用 readlines()?
文件很小(例如配置文件、CSV头)
需要多次访问不同的行(随机访问)
希望获取所有行后统一处理
四、更好的逐行读取方式:直接迭代文件对象
Python 文件对象本身是一个可迭代对象,可以直接在 for 循环中使用,这种方式内部使用 readline() 实现,但语法更简洁,且内存效率与 readline() 相同。
with open('data.txt', 'r') as f: for line in f: print(line.strip()) # 逐行处理
这是最推荐的按行读取方式:
代码简洁
自动处理缓冲和内存
支持大文件
可以配合 break 提前退出
五、处理换行符
默认情况下,readline() 和 readlines() 返回的字符串会保留行尾的换行符。通常你不需要换行符,可以使用 rstrip('\n') 或 .strip() 去掉。
withopen('data.txt', 'r') as f: for line in f: clean_line = line.rstrip('\n') # 只去掉末尾换行符 # 或 line.strip() 会去掉首尾所有空白字符
六、综合示例
示例1:读取文件并打印行号(使用迭代器)
with open('poem.txt', 'r', encoding='utf-8') as f: for i, line in enumerate(f, 1): print(f"{i:3}: {line.rstrip()}")
示例2:统计行数(最节省内存的方式)
def count_lines(file_path): count = 0 with open(file_path, 'r') as f: for _ in f: count += 1 return count
示例3:读取大文件的最后N行(使用 deque)
from collections import dequedef tail(file_path, n=10): with open(file_path, 'r') as f: return deque(f, maxlen=n)last_lines = tail('huge.log', 20)for line in last_lines: print(line.rstrip())
七、性能注意事项
readlines() 会一次性将所有行读入内存,对于大文件可能导致 MemoryError。
直接迭代文件对象或使用 readline() 循环,内存开销小,适合任何大小的文件。
如果需要随机访问所有行,但文件又很大,可以考虑逐行读取后存放到数据库或磁盘索引。
八、总结
| | |
|---|
for line in file: | 任何需要逐行处理的场景(首选) | |
readline() | | |
readlines() | | |
记住: