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
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()