Pergunta

Como faço para ver o EOF em Python? Encontrei um bug no meu código em que o último bloco de texto após o separador não é adicionado à lista de retorno. Ou talvez haja uma maneira melhor de expressar essa função?

Aqui está o meu código:

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
Foi útil?

Solução

Você pode achar mais fácil resolver isso usando 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]

Outra alternativa é usar um expressão regular Para combinar com os separadores:

def get_text_blocks(filename):
    import re
    seperator = re.compile('^-- -.*', re.M)
    with open(filename,'r') as f:
        return re.split(seperator, f.read())

Outras dicas

A condição de final de arquivo é válida assim que o for A declaração termina - essa parece a maneira mais simples de consertar especialmente este código (você pode extrair text_block.getvalue() No final, se você quiser verificar se não está vazio antes de anexá -lo).

Este é o problema padrão de emitir buffers.

Você não detecta o EOF - isso é desnecessário. Você escreve o último buffer.

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

Por que você precisa de Stringio aqui?

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

Editar: Corrigido a função, outras sugestões podem ser melhores, apenas queriam escrever uma função semelhante à original.

Editar: assumiu que o arquivo começa com "--", adicionando string vazia à lista que você pode "corrigir" o indexError ou você pode usar esta:

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

Mas ambas as versões parecem um pouco feias para mim, a versão Reg-Ex é muito mais limpa.

Esta é uma maneira rápida de ver se você tem um arquivo vazio:

if f.read(1) == '': 
 print "EOF"
 f.close()
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top