Как проверить наличие EOF в Python?
Вопрос
Как проверить наличие EOF в Python?Я обнаружил ошибку в своем коде, из-за которой последний блок текста после разделителя не добавляется в список возврата.Или, может быть, есть лучший способ выразить эту функцию?
Вот мой код:
def get_text_blocks(filename):
text_blocks = []
text_block = StringIO.StringIO()
with open(filename, 'r') as f:
for line in f:
text_block.write(line)
print line
if line.startswith('-- -'):
text_blocks.append(text_block.getvalue())
text_block.close()
text_block = StringIO.StringIO()
return text_blocks
Решение
Возможно, вам будет проще решить эту проблему, используя itertools.groupby.
def get_text_blocks(filename):
import itertools
with open(filename,'r') as f:
groups = itertools.groupby(f, lambda line:line.startswith('-- -'))
return [''.join(lines) for is_separator, lines in groups if not is_separator]
Другой альтернативой является использование регулярное выражение для соответствия разделителям:
def get_text_blocks(filename):
import re
seperator = re.compile('^-- -.*', re.M)
with open(filename,'r') as f:
return re.split(seperator, f.read())
Другие советы
Условие конца файла сохраняется, как только for
завершается — это кажется самым простым способом немного исправить этот код (вы можете извлечь text_block.getvalue()
в конце, если вы хотите убедиться, что он не пуст перед добавлением).
Это стандартная проблема с созданием буферов.
Вы не обнаруживаете EOF — в этом нет необходимости.Пишешь последний буфер.
def get_text_blocks(filename):
text_blocks = []
text_block = StringIO.StringIO()
with open(filename, 'r') as f:
for line in f:
text_block.write(line)
print line
if line.startswith('-- -'):
text_blocks.append(text_block.getvalue())
text_block.close()
text_block = StringIO.StringIO()
### At this moment, you are at EOF
if len(text_block) > 0:
text_blocks.append( text_block.getvalue() )
### Now your final block (if any) is appended.
return text_blocks
Зачем вам здесь нужен StringIO?
def get_text_blocks(filename):
text_blocks = [""]
with open(filename, 'r') as f:
for line in f:
if line.startswith('-- -'):
text_blocks.append(line)
else: text_blocks[-1] += line
return text_blocks
РЕДАКТИРОВАТЬ:Исправлена функция, другие предложения могут быть лучше, просто хотел написать функцию, похожую на исходную.
РЕДАКТИРОВАТЬ:Предполагается, что файл начинается с «-- -», добавив в список пустую строку, вы можете «исправить» IndexError или использовать эту:
def get_text_blocks(filename):
text_blocks = []
with open(filename, 'r') as f:
for line in f:
if line.startswith('-- -'):
text_blocks.append(line)
else:
if len(text_blocks) != 0:
text_blocks[-1] += line
return text_blocks
Но обе версии кажутся мне немного некрасивыми, версия с регулярным выражением намного чище.
Это быстрый способ узнать, есть ли у вас пустой файл:
if f.read(1) == '':
print "EOF"
f.close()