
文件对象在首次遍历后会停留在末尾位置,导致后续调用无法读取内容;解决方法是每次调用时重新打开文件,并避免使用全局变量,改用返回值传递结果。
文件对象在首次遍历后会停留在末尾位置,导致后续调用无法读取内容;解决方法是每次调用时重新打开文件,并避免使用全局变量,改用返回值传递结果。
在 Python 中,文件对象(如 open() 返回的句柄)本质上是一个迭代器 + 文件指针的组合。当你用 for line in datahandle: 遍历它时,Python 会逐行读取并移动内部指针;一旦到达文件末尾(EOF),该指针不会自动重置。因此,第二次调用同一函数时,datahandle 已处于 EOF 状态,循环体一次也不执行,count 保持为 0。
直接修复原代码的关键在于:不复用已耗尽的文件句柄,而是在每次调用函数时新建一个独立、可读的文件对象。同时,应摒弃 global count 的设计——它不仅破坏封装性,还容易引发状态污染和并发风险。
以下是推荐的健壮实现方式(使用 with 语句确保资源安全):
def count_lines(filename="dataset.txt"):
with open(filename, "r", encoding="utf-8") as f:
count = 0
for line in f:
count += 1
return count
# 正确调用示例(可无限次重复)
print(count_lines()) # 输出: 10
print(count_lines()) # 输出: 10
print(count_lines()) # 输出: 10✅ 优势说明:
-
with open(...)自动处理文件打开与关闭,即使发生异常也不会泄露句柄; - 每次调用都获得全新的、位于文件开头的文件对象,行为完全可预测;
- 函数无副作用、无全局依赖,符合纯函数设计原则,易于测试与复用;
- 显式指定
encoding="utf-8"避免跨平台编码问题(尤其 Windows 记事本默认保存为 ANSI/GBK)。
⚠️ 注意事项:
- 若需高频统计大文件行数,可考虑更高效方式(如
sum(1 for _ in f)或系统命令wc -l),但上述循环方案在可读性与兼容性上仍是首选; - 切勿在函数外保留
open()返回的句柄并反复传入——这正是问题根源; -
rstrip()在仅统计行数时非必需(空行、换行符不影响计数),若后续需内容处理再添加。
总之,将文件打开逻辑内聚于函数内部,是实现可重复、可维护、可预测行数统计的最简最优解。

















