Pregunta

Estoy escribiendo un script que registra los errores de otro programa y reinicia el programa donde se detuvo cuando encuentra un error. Por cualquier motivo, los desarrolladores de este programa no consideraron necesario poner esta funcionalidad en su programa de forma predeterminada.

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 emite un error, le brinda la información de referencia que necesita para rastrear el error, es decir, la interfaz de usuario, la sección (título o 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 de la sección). La forma en que parecía tener sentido hacer esto es:

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

No veo cómo esto haría que perdiera datos, pero Python cree que sí y dice ValueError: la mezcla de iteración y los métodos de lectura perderían datos . ¿Alguien sabe cómo hacer esto correctamente?

¿Fue útil?

Solución

Obtienes el ValueError porque tu código probablemente tenga para la línea en el original: además de original.readline () . Una solución fácil que soluciona el problema sin hacer que su programa sea más lento o consuma más memoria está cambiando

for line in original:
    ...

a

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

Otros consejos

Use para y enumerate .

Ejemplo:

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

NOTA : esto supone que ya estás limpiando los manejadores de archivos, etc.

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

Suponiendo que solo necesita 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 los errores de StopIteration (si el archivo tiene menos líneas).

Aquí hay una versión sin el patrón feo 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
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top