Frage

Ich schreibe ein Skript, das Fehler von einem anderen Programm protokolliert und startet das Programm, wo er aufgehört hat, wenn ein Fehler auftritt. Aus welchen Gründen auch immer, haben die Entwickler dieses Programms nicht das Gefühl, es notwendig, diese Funktionalität in ihr Programm standardmäßig zu setzen.

Wie auch immer, nimmt das Programm eine Eingabedatei, analysiert sie und erstellt eine Ausgabedatei. Die Eingabedatei ist in einem bestimmten Format:

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

Wenn das Programm einen Fehler wirft, es gibt Ihnen die Referenzinformationen benötigen Sie den Fehler verfolgen - nämlich die UI, welcher Abschnitt (Titel oder Zusammenfassung), und die Zeilennummer relativ zum Anfang des Titels oder abstrakt. Ich will die beanstandeten Sätze aus der Eingabedatei mit einer Funktion protokollieren, die die Referenznummer und die Datei nimmt, findet den Satz, und meldet es. Der beste Weg, was ich denken konnte, es zu tun ist das Fahren nach vorne durch die Datei, die eine bestimmte Anzahl von Malen (nämlich n-mal, wobei n die Zeilennummer relativ zum Anfang des seciton ist). Die Art und Weise, den Sinn schien zu machen, dies zu tun ist:

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

Ich sehe nicht, wie dies würde ich Daten verlieren, aber Python denkt, es würde und sagt ValueError: Mixing iteration and read methods would lose data. Wer weiß, wie diese richtig zu machen?

War es hilfreich?

Lösung

Sie erhalten die Valueerror, weil Ihr Code wahrscheinlich zusätzlich hat for line in original: original.readline(). Eine einfache Lösung, die das Problem behebt, ohne das Programm langsamer zu machen oder verbrauchen mehr Speicher ändern

for line in original:
    ...

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

Andere Tipps

Verwenden for und enumerate .

Beispiel:

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

Hinweis . Dies vorausgesetzt, dass Sie bereits die Reinigung Ihrer Datei-Handles nach oben, etc

Auch die Takewhile Funktion könnte sich als nützlich erweisen, wenn Sie ein bevorzugen funktioneller Geschmack.

Angenommen, Sie benötigen nur eine Zeile, dies hilfreich sein könnte

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'

Sie möchten vielleicht StopIteration Fehler abzufangen (wenn die Datei weniger Zeilen hat).

Hier ist eine Version ohne die hässlichen while True Muster und ohne andere Module:

for line in iter(original.readline, ''):
    if …:   # to the beginning of the title or abstract
        for i in range(lineNumber):
            print original.readline(),
        break
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top