2009-05-05 13 views
21

Piszę skrypt, który rejestruje błędy z innego programu i uruchamia ponownie program w miejscu, w którym przerwał działanie po napotkaniu błędu. Z jakichkolwiek przyczyn twórcy tego programu domyślnie nie uważali za konieczne umieszczania tej funkcji w swoim programie.Mieszanie plików i pętli

W każdym razie program pobiera plik wejściowy, analizuje go i tworzy plik wyjściowy. Plik wejściowy jest w określonym formacie:

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

Gdy program zgłasza błąd, to daje informacje odniesienia potrzebne do śledzenia błędów - mianowicie, interfejs użytkownika, który odcinek (tytuł lub streszczenie) i numer linii odnoszący się do początku tytułu lub streszczenia. Chcę zapisać niepoprawne zdania z pliku wejściowego za pomocą funkcji, która pobiera numer referencyjny i plik, znajduje zdanie i loguje je. Najlepszym sposobem na zrobienie tego jest poruszanie się po pliku określoną liczbę razy (mianowicie n razy, gdzie n jest numerem linii względem początku sekundy). Sposób, który wydawał się mieć sens, aby to zrobić:

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

nie widzę w jaki sposób miałoby to mnie stracić dane, ale Python myśli, że będzie, i mówi: ValueError: Mixing iteration and read methods would lose data. Czy ktoś wie, jak to zrobić właściwie?

+1

-1: Kod brakuje fragmentu. Prawdopodobnie w wyświetlonym kodzie brakuje "czegoś w oryginale". –

Odpowiedz

44

Otrzymasz błąd ValueError, ponieważ Twój kod prawdopodobnie ma for line in original: oprócz original.readline(). Proste rozwiązanie, które rozwiązuje ten problem bez dokonywania program wolniej lub zużywają więcej pamięci zmienia

for line in original: 
    ... 

do

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

Uderzyłeś paznokciem w głowę - ja * używałem *, tak jak i podczas. To była najszybsza poprawka. Dziękuję i dziękuję również za odpowiedzi innych osób. –

+0

też mi pomógł. Dziękuję Ci. – nish

+0

To nie działa. Wpada w nieskończoną pętlę. Wierzę, że eof nie zwraca wartości None. – lionel319

10

Użyj for i enumerate.

Przykład:

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

UWAGA: Zakłada jesteś już sprzątanie swoich uchwyty pliku itp

Ponadto, funkcja takewhile może okazać się przydatna, jeśli wolisz smak bardziej funkcjonalną.

0

Zakładając trzeba tylko jedną linię, może to być pomocne

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' 

Możesz chcieć złapać błędy StopIteration (jeśli plik zawiera mniej wierszy).

0

Oto wersja bez brzydkiego while True wzoru i bez innych modułów:

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