2010-11-11 17 views
10

Piszę plik Pythona, który musi zostać odczytany w kilku plikach różnych typów. Czytam pliki w linii po linii z tradycyjnym for line in f po użyciu f = open("file.txt", "r").Czy metoda readline w Pythonie rozpoznaje obie odmiany linii?

Wygląda na to, że nie działa dla wszystkich plików. Domyślam się, że niektóre pliki kończą się różnymi kodowaniami (takimi jak \ r \ n versus \ r). Mogę przeczytać cały plik i zrobić ciąg podzielony na \ r, ale to jest bardzo kosztowne i wolałbym nie. Czy istnieje sposób, aby metoda readline w Pythonie rozpoznała oba warianty końca linii?

Odpowiedz

17

pomocą powszechnego poparcia nowej linii - patrz http://docs.python.org/library/functions.html#open

Ponadto średnia fopen() tryb wartości mogą być 'U' lub 'rU'. Python jest zwykle zbudowany z uniwersalną obsługą znaków nowej linii ; dostarczanie "U" otwiera plik w postaci pliku tekstowego, ale linie mogą być zakończone przez jedną z następujących wartości: Konwencja końca linii "Konwencja Unix" \ n ', Konwencja Macintosh' \ r 'lub Konwencja Windows '\ r \ n'. Wszystkie te reprezentacje zewnętrzne są postrzegane jako "\ n" przez program Python. Jeśli Python jest zbudowany bez obsługi uniwersalnej newline, tryb z "U" to to samo, co zwykły tryb tekstowy. Zauważ, że tak otwarte obiekty plików mają atrybut o nazwie newlines, który ma wartość Brak (jeśli nie było jeszcze żadnych nowych linii, ), '\ n', '\ r', '\ r \ n' lub krotka zawierająca wszystkie typy nowej linii.

+0

oczywiście „Macintosh” konwencja kończące wiersz kończy się „\ r” (ASCII 13, CR) był również używany przez prawie każdy 8-bitowy mikrokomputer przed komputerem Macintosh, w tym Apple II, Commodore i Atari. –

+0

Zobacz moją odpowiedź na pytanie dotyczące twojej odpowiedzi. –

0

Można spróbować użyć podejście generator czytać wiersze przez siebie i ignorować wszelkie znaki EOL:

def readlines(f): 
    line = [] 
    while True: 
     s = f.read(1) 
     if len(s) == 0: 
      if len(line) > 0: 
       yield line 
      return 
     if s in ('\r','\n'): 
      if len(line) > 0: 
       yield line 
      line = [] 
     else: 
      line.append(s) 

for line in readlines(yourfile): 
    # ... 
+0

Ups, właśnie zauważyłem posta bgportera - jeśli jest na to natywna pomoc, to najwyraźniej nie będziesz potrzebował tego generatora. :) – Kos

+0

Twoje rozwiązanie odrzuca puste linie (np. '\ N \ n' lub' \ r \ n \ r \ n'), generuje listy znaków zamiast ciągów i będzie działało bardzo wolno z powodu czytania postaci w czasie bez buforowanie. Nie jestem pewien, czy praca z listami znaków zamiast ciągów poprawia wydajność. –

Powiązane problemy