一、开篇:三种方式,各有场景
Python文件对象提供了三种读取方式:read()一次性全读、readline()逐行读、readlines()读成行列表。选择哪种方式取决于文件大小和后续处理需求。
⌨️ 先看三种方式的基本对比:
python
# 准备测试文件
with open("sample.txt", "w", encoding="utf-8") as f:
f.write("第一行内容\n")
f.write("第二行内容\n")
f.write("第三行内容\n")
# === 方式一:read() ------ 读取全部 ===
with open("sample.txt", "r", encoding="utf-8") as f:
all_content = f.read()
print(f"read(): {repr(all_content)}")
# '第一行内容\n第二行内容\n第三行内容\n'
# === 方式二:readline() ------ 读取一行 ===
with open("sample.txt", "r", encoding="utf-8") as f:
line1 = f.readline()
line2 = f.readline()
print(f"readline(): {repr(line1)}, {repr(line2)}")
# '第一行内容\n', '第二行内容\n'
# === 方式三:readlines() ------ 读取所有行到列表 ===
with open("sample.txt", "r", encoding="utf-8") as f:
lines = f.readlines()
print(f"readlines(): {lines}")
# ['第一行内容\n', '第二行内容\n', '第三行内容\n']
二、read() ------ 一把梭
2.1 基本用法
python
# read(size) ------ 读取最多size个字符(文本模式)或字节(二进制模式)
# 不指定size或size=-1 → 读取全部
with open("sample.txt", "r", encoding="utf-8") as f:
# 读取全部
print("全部内容:")
print(f.read())
# 分块读取
with open("sample.txt", "r", encoding="utf-8") as f:
print("\n分块读取:")
chunk = f.read(5) # 一次读5个字符
while chunk:
print(f" chunk: {repr(chunk)}")
chunk = f.read(5)
# 💡 read()的特点:
# - 返回一个字符串(或bytes)
# - 适合小文件------一次加载到内存
# - size参数可以控制每次读取的量(处理大文件时有用)
# - 读到文件末尾时返回空字符串 ''
2.2 判断文件是否读完
python
# 文件对象的可读性判断
with open("sample.txt", "r", encoding="utf-8") as f:
content = f.read()
# 再次读取
more = f.read()
print(f"第二次读取: {repr(more)}") # '' ------ 空字符串表示读完了
print(f"长度为0: {len(more) == 0}") # True
三、readline() ------ 逐行读
3.1 基本用法
python
# readline() ------ 读取一行(包括行尾的\n)
# 返回空字符串表示读完了
with open("sample.txt", "r", encoding="utf-8") as f:
line = f.readline()
while line:
# strip()去掉换行符
print(f"行内容: {line.rstrip()}")
line = f.readline()
# 但更常见的做法是用for循环------文件对象本身就是可迭代的!
with open("sample.txt", "r", encoding="utf-8") as f:
for line in f: # 文件对象是行迭代器
print(f"行: {line.rstrip()}")
# 💡 文件对象就是最好的"逐行读取器"------不需要显式调用readline()
3.2 读取指定大小
python
# readline(size) ------ 读取一行,但不超过size个字符
with open("sample.txt", "r", encoding="utf-8") as f:
# 只读一行中的前3个字符
partial = f.readline(3)
print(f"读3个字符: {repr(partial)}") # '第一'
# 继续读这一行的剩余部分
rest = f.readline()
print(f"这一行剩余: {repr(rest)}") # '行内容\n'
四、readlines() ------ 读成列表
4.1 基本用法
python
# readlines() ------ 返回包含所有行的列表,每行末尾保留\n
with open("sample.txt", "r", encoding="utf-8") as f:
lines = f.readlines()
print(f"行数: {len(lines)}")
for i, line in enumerate(lines, 1):
print(f" 第{i}行: {repr(line)}")
# ⚠️ readlines()会把整个文件加载到内存的列表中
# 大文件慎用!如果文件有1000万行,内存直接爆了
# 💡 什么时候用readlines()?
# 1. 文件很小(几十KB到几MB)
# 2. 需要对行做随机访问(通过索引跳转)
# 3. 需要多次遍历行
4.2 readlines() vs list(f)
python
# 两种方式获得行列表
with open("sample.txt", "r", encoding="utf-8") as f:
lines1 = f.readlines()
with open("sample.txt", "r", encoding="utf-8") as f:
lines2 = list(f) # 等价于readlines()
print(lines1 == lines2) # True
# 💡 list(f)更短,效果相同,都是把所有行读入列表
五、选择指南
5.1 按场景选方法
python
# 场景一:小文件(几MB以内) ------ read()或readlines()
def process_small_file(filepath):
"""处理小文件------一次全读"""
with open(filepath, "r", encoding="utf-8") as f:
content = f.read()
return content.upper() # 全文处理
# 场景二:大文件(几百MB~几GB) ------ for循环逐行读
def process_large_file(filepath):
"""处理大文件------逐行读取,不占内存"""
line_count = 0
with open(filepath, "r", encoding="utf-8") as f:
for line in f:
# 处理每一行
if "ERROR" in line:
line_count += 1
return line_count
# 场景三:超大文件分块读取 ------ read(size)
def process_huge_file(filepath, chunk_size=8192):
"""处理超大文件------分块读取"""
with open(filepath, "r", encoding="utf-8") as f:
chunk = f.read(chunk_size)
while chunk:
# 处理这一块数据
process_chunk(chunk)
chunk = f.read(chunk_size)
# 场景四:需要带行号的处理
def process_with_line_numbers(filepath):
"""带行号的处理"""
with open(filepath, "r", encoding="utf-8") as f:
for line_num, line in enumerate(f, 1):
print(f"第{line_num}行: {line.rstrip()}")
5.2 性能对比
python
import time
def benchmark_read_methods(filepath):
"""性能基准测试"""
methods = {
"read()": lambda f: f.read(),
"readlines()": lambda f: f.readlines(),
"for line in f": lambda f: [line for line in f],
"readline() loop": lambda f: (lambda: [f.readline() for _ in iter(lambda: f.readline(), '')])(),
}
for name, method in methods.items():
with open(filepath, "r", encoding="utf-8") as f:
start = time.perf_counter()
try:
method(f)
except:
pass
elapsed = time.perf_counter() - start
print(f"{name}: {elapsed:.4f}秒")
# 典型结果(中等文件):
# read()和for line in f通常最快
# readlines()差不多------它们都是C实现的
# readline()循环最慢------每次调用有函数开销
六、总结
三种读取方式各有最适合的场景。选择的标准不是"哪种更高级",而是"哪种更适合你当前的需求"。
💡 快速决策:
| 文件大小 | 需求 | 推荐方式 |
|---|---|---|
| 小文件 | 全读入内存处理 | read() |
| 大文件 | 逐行处理 | for line in f |
| 超大文件 | 分块处理 | read(chunk_size) |
| 小文件 | 需要行列表 | readlines() 或 list(f) |
✅ 默认用for line in f------它是处理文件最Pythonic、最内存友好的方式。