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

对于我正在做的一个练习,我尝试使用 read()方法读取给定文件的内容两次。奇怪的是,当我第二次调用它时,它似乎没有以字符串的形式返回文件内容?

这是密码

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()两次?我必须重置文件句柄吗?或者关闭/重新打开文件?

88369 次浏览

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

To answer your question directly, once a file has been read, with read() you can use seek(0) to return the read cursor to the start of the file (docs are 给你). If you know the file isn't going to be too large, you can also save the read() output to a variable, using it in your findall expressions.

不要忘记关闭文件后,你完成了它。

The read pointer moves to after the last read byte/character. Use the seek() method to rewind the read pointer to the beginning.

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

可以使用 seek移动文件位置。或者在您的情况下更好的做法是执行一个 read()并保留两个搜索的结果。

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

What I'll add is that in your particular case, you don't need to seek back to the start or reopen the file, you can just store the text that you've read in a local variable, and use it twice, or as many times as you like, in your program:

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

read() 消耗.所以,你可以把 重置的文件,或者 寻找的开头再重新读一遍。或者,如果它适合您的任务,您可以使用 read(n)只消耗 n字节。

正如其他答案所建议的那样,您应该使用 seek()

我只写一个例子:

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

我总是觉得阅读方法有点像在黑暗的小巷里散步。你往下走一点,然后停下来,但是如果你没有数你的步数,你就不知道你走了多远。Seek 通过重新定位给出解决方案,另一个选项是 Tell,它返回沿文件的位置。也许 Python 文件 api 可以将 read 和 find 组合到 read _ from (position,byte)中,使其更简单——直到您应该读取 这一页为止。