为什么我不能在打开的文件上调用read()两次?

对于我正在做的练习,我试图用read()方法read()给定文件的内容两次。 奇怪的是,当我第二次调用它,它似乎并没有返回文件内容作为一个string?

这是代码

 f = f.open() # get the year match = re.search(r'Popularity in (\d+)', f.read()) if match: print match.group(1) # get all the names matches = re.findall(r'<td>(\d+)</td><td>(\w+)</td><td>(\w+)</td>', f.read()) if matches: # matches is always None 

当然,我知道这不是最有效或最好的方式,这不是重点。 关键是,为什么我不能调用read()两次? 我必须重置文件句柄吗? 或closures/重新打开文件,以此来做到这一点?

调用read()会读取整个文件,并将读取光标留在文件的末尾(没有其他可读的内容)。 如果你正在读取一定数量的行,你可以使用readline()readlines()或迭代行中for line in handle:

要直接回答你的问题,一旦一个文件被读取,用read()你可以使用seek(0)返回读光标到文件的开头(文档在这里 )。 如果你知道这个文件不会太大,你也可以将read()输出保存到一个variables中,在findallexpression式中使用它。

PS。 在完成之后,不要忘记closures文件;)

读指针移到最后读取的字节/字符之后。 使用seek()方法将读指针倒回到开头。

到目前为止,回答这个问题的每个人都是绝对正确的read()在文件中移动,所以调用它之后,就不能再调用它了。

我要补充的是,在你的具体情况下,你不需要重新开始或者重新打开文件,你可以将你读到的文本存储在一个局部variables中,然后使用它两次,或者在你的程序中,尽可能多的多次:

 f = f.open() text = f.read() # read the file into a local variable # get the year match = re.search(r'Popularity in (\d+)', text) if match: print match.group(1) # get all the names matches = re.findall(r'<td>(\d+)</td><td>(\w+)</td><td>(\w+)</td>', text) if matches: # matches will now not always be None 

是的,如上所述…

我会写一个例子:

 >>> a = open('file.txt') >>> a.read() #output >>> a.seek(0) >>> a.read() #same output 

每个打开的文件都有相关的位置。
当你读()你从那个位置读。 例如, read(10)从新打开的文件中读取前10个字节,然后再read(10)读取下10个字节。 不带参数的read()会读取文件的所有内容,并将文件位置保留在文件末尾。 下一次你调用read() ,没有什么可读的。

您可以使用seek来移动文件位置。 或者在你的情况下可能会更好的做一个read()并保持两个search的结果。

read() 消耗 。 所以,你可以重新设置文件,或重新阅读之前寻求启动。 或者,如果它包含你的任务,你可以使用read(n)来只消耗n个字节。

我总是发现阅读的方法在黑暗的小巷里散步。 你稍微停下来,但是如果你不计算你的步数,你不知道你有多远。 Seek通过重新定位给出了解决scheme,另一个选项是Tell,它返回文件的位置。 可能是Python文件API可以结合读取和查find一个read_from(位置,字节),使其更简单 – 直到发生这种情况,你应该阅读本页面 。