2010-01-03 9 views
8

¿Cómo verifico EOF en Python? Encontré un error en mi código donde el último bloque de texto después del separador no se agrega a la lista de devolución. ¿O tal vez hay una mejor manera de expresar esta función?¿Cómo verificar EOF en Python?

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 
+0

oportunidad ahora, fijo mi función x2 = ( –

Respuesta

3

Puede que le resulte más fácil resolver 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 un regular expression 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()) 
+0

Respuestas interesantes Mark. No sabía sobre itertools, gracias. – ajushi

+0

+1 Para la versión RegEx, la versión de itertools es ligeramente críptica. –

+0

Probé la versión de itertools en el intérprete ineractivo y devuelve una cadena vacía. lines parece ser un objeto itertools._grouper – ajushi

1

La EOF condición se cumple en cuanto el comunicado for termina - que parece la forma más sencilla de solucionar minorly este código (se puede extraer text_block.getvalue() al final si desea verificar que no esté vacío antes de agregarlo).

+0

Gracias Alex Mi solución sucia era añadir text_blocks .append (text_block.getvalue()) y text_block.close() debajo del bloque for. Funciona pero no es DRY:/ – ajushi

0

¿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 se puede "fijar" el IndexError o puede utilizar éste:

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 parecen Un poco feo para mí, la versión reg-ex es mucho más limpia.

+0

Aún falta el último bloque –

+0

¿Podría proporcionar datos de entrada de prueba? –

+0

@maiku the test datos de entrada es un volcado de SQL por phpMyAdmin. Necesito separar el texto en blo cks separados por una línea que comienza con - -... – ajushi

0

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

No detecta EOF, eso es innecesario. Usted escribe el ú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 
1
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 
-2

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

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

No, porque no hay espacio entre el ''. Probé esto en un archivo con solo un espacio, y no detecté que el archivo estaba vacío. – AndroidDebaser

+1

Si un archivo contiene un espacio, no está vacío. – Dave