Pregunta

¿Cómo puedo comprobar para EOF en Python? He encontrado un fallo en mi código donde no se añade el último bloque de texto después del separador a la lista de regreso. O tal vez hay una mejor manera de expresar esta función?

Aquí está mi 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
¿Fue útil?

Solución

Puede que le resulte más fácil de solucionar esto 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]

Otra alternativa es utilizar una expresión regular para que coincida con los 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())

Otros consejos

La condición de fin de archivo contiene lo antes de la expiración de la declaración for - que parece la forma más sencilla para fijar minorly este código (se puede extraer text_block.getvalue() al final si desea comprobar no está vacío antes de añadir que) .

Este es el problema estándar con emisores de buffers.

No detectar EOF - que es innecesario. Se escribe la última memoria intermedia.

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 qué necesita StringIO aquí?

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:. Fija la función, otras sugerencias podrían ser mejores, sólo quería escribir una función similar a la original

EDIT: asumió el archivo comienza con "- -", añadiendo cadena vacía a la lista, podrá "fijar" el IndexError o puede utilizar la siguiente:

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

Pero ambas versiones se ven un poco feo para mí, la versión reg-ex es mucho más limpio.

Esta es una forma rápida de ver si tiene un archivo vacío:

if f.read(1) == '': 
 print "EOF"
 f.close()
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top