Python3中readlines或enumerate读取文件是否会导致文件流为空?
python3 环境 代码如下:
file_path = os.getcwd() + "/test.txt"
project_file = open(file_path,"r")
#list_file = project_file.readlines()
for index, line in enumerate(project_file):
print("index=%d,linex=%s"%(index,line))
test.txt 里面有一些任意文本内容,在注释掉第三行的情况下,下面的 print 能正常打印文本内容。 去除第三行的注释后,下面的 print 无打印,也就是 project_file 为空了? 同样的把 for 循环放到 readlines 上面,第一个 print 能正常打印文本内容,但是也会导致 list_file 为空,print 打出的长度为 0,代码如下:
file_path = os.getcwd() + "/test.txt"
project_file = open(file_path,"r")
for index, line in enumerate(project_file):
print("index=%d,linex=%s"%(index,line))
list_file = project_file.readlines()
print(len(list_file))
我的问题是:enumerate 或者 readlines 操作过一次文件流后,是否会导致文件流为空?或者是我的使用有问题,我是 python 新手,求大佬解惑
Python3中readlines或enumerate读取文件是否会导致文件流为空?
事实上是不会的
In [1]: with open(file=‘README.md’, mode=‘r’, encoding=‘utf8’) as f:
…: res = f.readlines()
…:
In [2]: res
Out[2]: [‘这次会有比较多的代码,但核心代码都是你已经亲自写过的~\n’, ‘请注意阅读顺序,ext 会作为课外阅读内容~’]
In [3]: for index, value in enumerate(res):
…: print(index, value)
…:
0 这次会有比较多的代码,但核心代码都是你已经亲自写过的~
1 请注意阅读顺序,ext 会作为课外阅读内容~
这个问题其实挺常见的,很多人都会遇到。简单来说,是的,如果你用 readlines() 或 for line in enumerate(file) 完整地读取了一个文件对象,那么这个文件对象的“流”就到达了末尾(EOF)。 之后你再对这个文件对象进行读取操作,比如再次调用 read()、readline() 或进行迭代,就不会得到任何数据了。
这是因为文件对象内部有一个“指针”,用来记录当前读取的位置。readlines() 和 enumerate(file)(本质上就是迭代文件对象)都会从头读到尾,指针就移到了文件末尾。
看个例子就明白了:
# 假设我们有一个文件 test.txt,内容为:
# Line 1
# Line 2
# Line 3
with open('test.txt', 'r') as f:
# 第一次读取:使用 readlines(),会消耗掉整个文件流
lines = f.readlines()
print("第一次读取 (readlines):", lines) # 输出:['Line 1\n', 'Line 2\n', 'Line 3\n']
# 此时文件流指针已在末尾
# 第二次尝试读取:什么也得不到
second_read = f.readlines()
print("第二次读取 (readlines):", second_read) # 输出:[]
# 同样,尝试 readline() 也返回空字符串
line = f.readline()
print("尝试 readline():", repr(line)) # 输出:''
# 迭代也不会产生任何结果
for i, line in enumerate(f):
print("这行不会被执行")
解决办法很简单:
-
重新打开文件:最直接的方法,每次读取都重新用
open()打开。with open('test.txt', 'r') as f: lines1 = f.readlines() with open('test.txt', 'r') as f: lines2 = f.readlines() # 现在 lines2 又有数据了 -
将内容保存到变量:如果文件不大,第一次读取后把内容(比如列表
lines)存下来,后面直接复用这个变量,不需要重新读文件。 -
移动文件指针:使用
f.seek(0)将指针移回文件开头,然后就可以再次读取了。with open('test.txt', 'r') as f: lines1 = f.readlines() f.seek(0) # 指针回到开头 lines2 = f.readlines() # 现在 lines2 也有数据了
总结:文件对象是一次性消耗品,读完记得重置指针或重新打开。
我知道了,文件指针的问题,被移动到结尾了。谢谢。readlines 前 project_file.seek(0, 0)就好了

