Вопрос

Как проверить наличие 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()
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top