Как проверить 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

6 ответов


возможно, Вам будет проще решить эту проблему с помощью 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() в конце, если вы хотите проверить, что он не пуст, прежде чем добавлять его).


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

EDIT: исправлена функция, другие предложения могут быть лучше, просто хотел написать функцию, похожую на оригинальную.

EDIT: предполагается, что файл начинается с"-- -", добавив пустую строку в список, вы можете" исправить " 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

но обе версии выглядят немного уродливыми для меня, версия reg-ex намного чище.


Это стандартная проблема с излучающими буферами.

вы не обнаруживаете 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

это быстрый способ узнать, есть ли у вас пустой файл:

if f.read(1) == '': 
 print "EOF"
 f.close()