Почему я не могу вызвать 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() в два раза? Мне нужно сбросить дескриптор файла? Или закрыть / открыть файл для того, чтобы сделать это?
7 ответов:
вызов
read()считывает весь файл и оставляет курсор чтения в конце файла (только для чтения). Если вы хотите прочитать определенное количество строк за один раз, вы можете использоватьreadline(),readlines()или перебирать строки сfor line in handle:.чтобы ответить на ваш вопрос напрямую, как только файл был прочитан, с
read()можно использоватьseek(0)чтобы вернуть курсор чтения в начало файла (docs are здесь). Если вы знаете, что файл не является будет слишком большой, вы также можете сохранитьread()вывод в переменную, используя ее в выражениях findall.Ps. Не забудьте закрыть файл после того, как вы закончите с ним ;)
да, как выше...
Я напишу только пример:
>>> a = open('file.txt') >>> a.read() #output >>> a.seek(0) >>> a.read() #same output
всем, кто ответил на этот вопрос до сих пор абсолютно прав -
read()перемещается по файлу, поэтому после того, как вы его вызвали, Вы не можете вызвать его снова.Я добавлю, что в вашем конкретном случае вам не нужно искать назад к началу или снова открывать файл, вы можете просто сохранить текст, который вы прочитали в локальной переменной, и использовать его дважды или столько раз, сколько вам нравится, в вашей программе:
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
указатель чтения перемещается после последнего прочитанного байта / символа. Используйте
seek()метод для перемотки указателя чтения в начало.
каждый открытый файл имеет соответствующую позицию.
Когда вы читаете (), Вы читаете с этой позиции. Напримерread(10)считывает первые 10 байт из вновь открытого файла, затем еще одинread(10)считывает следующие 10 байт.read()без аргументов считывает все содержимое файла, оставляя позицию файла в конце файла. В следующий раз, когда вы позвонитеread()читать нечего.можно использовать
seekдля перемещения позиции в файле. Или, возможно, лучше в вашем случае будет быть, чтобы сделать одинread()и сохранить результат для обоих поисков.
read()потребляет. Так что, вы могли бы сброс файл, или искать для начала перед повторным чтением. Или, если это соответствует вашей задаче, вы можете использоватьread(n)потреблять толькоnбайт.
Я всегда нахожу метод чтения чем-то вроде прогулки по темному переулку. Вы спускаетесь немного вниз и останавливаетесь, но если вы не считаете свои шаги, вы не уверены, как далеко вы находитесь. Seek дает решение путем перемещения, другой вариант-сказать, который возвращает позицию вдоль файла. Может быть, Python file api может комбинировать чтение и поиск в read_from(позиция, байты), чтобы сделать его проще - пока это не произойдет, вы должны прочитать на этой странице.
Comments