2009-05-05 12 views
21

Estoy escribiendo una secuencia de comandos que registra errores de otro programa y reinicia el programa donde se quedó cuando se produce un error. Por las razones que sean, los desarrolladores de este programa no consideraron necesario incluir esta funcionalidad en su programa de forma predeterminada.Mezcla de archivos y bucles

De todos modos, el programa toma un archivo de entrada, lo analiza y crea un archivo de salida. El archivo de entrada está en un formato específico:

UI - 26474845 
TI - the title (can be any number of lines) 
AB - the abstract (can also be any number of lines) 

Cuando el programa genera un error, que siempre tenga la información de referencia que necesita para rastrear el error - a saber, la interfaz de usuario, que la sección (título o el resumen), y el número de línea relativo al comienzo del título o resumen. Quiero registrar las oraciones ofensivas del archivo de entrada con una función que toma el número de referencia y el archivo, encuentra la oración y la registra. La mejor manera de pensar en hacerlo es avanzar en el archivo un número específico de veces (es decir, n veces, donde n es el número de línea relativo al comienzo del sector). La forma en que parecía tener sentido de hacer esto es:

i = 1 
while i <= lineNumber: 
    print original.readline() 
    i += 1 

No veo cómo esto me haría perder datos, pero Python cree que lo haría, y dice ValueError: Mixing iteration and read methods would lose data. ¿Alguien sabe cómo hacer esto correctamente?

+1

-1: Código falta en el fragmento. Probablemente haya un "para algo en el original:" que falta en el código que se muestra. –

Respuesta

44

Obtiene el ValueError porque su código probablemente tenga for line in original: además de original.readline(). Una solución fácil, que soluciona el problema sin hacer que su programa más lento o consume más memoria está cambiando

for line in original: 
    ... 

a

while True: 
    line = original.readline() 
    if not line: break 
    ... 
+1

Le pegaste al clavo en la cabeza: * * * estaba usando, así como también. Esta fue la solución más rápida. Gracias y gracias por las respuestas de todos los demás también. –

+0

me ayudó también. gracias. – nish

+0

Esto no parece funcionar. Se mete en un bucle infinito. Creo que el eof no devuelve un valor None. – lionel319

10

Utilice for y enumerate.

Ejemplo:

for line_num, line in enumerate(file): 
    if line_num < cut_off: 
     print line 

NOTA: Esto asume que ya está limpiando sus identificadores de archivo, etc.

Además, la función takewhile podría ser útil si usted prefiere un sabor más funcional.

0

Asumiendo que requiere sólo una línea, esto podría ser de ayuda

import itertools 

def getline(fobj, line_no): 
    "Return a (1-based) line from a file object" 
    return itertools.islice(fobj, line_no-1, line_no).next() # 1-based! 

>>> print getline(open("/etc/passwd", "r"), 4) 
'adm:x:3:4:adm:/var/adm:/bin/false\n' 

Es posible que desee detectar errores StopIteration (si el archivo tiene menos líneas).

0

Aquí hay una versión sin el patrón fea while True y sin otros módulos:

for line in iter(original.readline, ''): 
    if …: # to the beginning of the title or abstract 
     for i in range(lineNumber): 
      print original.readline(), 
     break