2010-11-11 2 views
10

Ich schreibe eine Python-Datei, die mehrere Dateien verschiedener Typen einlesen muss. Ich lese die Dateien Zeile für Zeile mit der traditionellen for line in f nach der Verwendung von f = open("file.txt", "r").Lassen Sie die Readline-Methode von Python beide End-of-Line-Varianten erkennen?

Dies scheint nicht für alle Dateien zu funktionieren. Meine Vermutung ist, dass einige Dateien mit verschiedenen Kodierungen enden (wie zB \ r \ n gegen \ r \ n). Ich kann die ganze Datei einlesen und eine Zeichenfolge aufteilen, aber das ist sehr teuer und ich würde es lieber nicht tun. Gibt es eine Möglichkeit, die readline-Methode von Python dazu zu bringen, beide End-of-Line-Varianten zu erkennen?

Antwort

17

die universelle Neue-Zeile-Unterstützung verwenden - http://docs.python.org/library/functions.html#open

Neben dem Standard fopen() Werte Modus werden können 'U' oder 'rU' sehen. Python ist in der Regel mit Universal Newline-Unterstützung gebaut; 'U' zu liefern öffnet die Datei als eine Textdatei, aber die Zeilen können durch eines der folgenden enden: die Unix-Endkonvention '\ n', die Macintosh-Konvention '\ r', oder die Windows Konvention '\ r \ n'. Alle diese externen Darstellungen sind als '\ n' von dem Python-Programm gesehen. Wenn Python ist ohne Universal Newline-Unterstützung ein Modus mit 'U' ist die identisch wie normale Textmodus. Beachten Sie, dass die so geöffneten Dateiobjekte auch ein -Attribut mit dem Namen newlines haben, das einen -Wert von None hat (wenn noch keine Zeilenumbrüche vorhanden sind), '\ n', '\ r', '\ r \ n' oder ein Tupel mit allen Newline-Typen gesehen.

+0

Natürlich ist die „Macintosh“ Konvention Linie endet endet mit ‚\ r‘ (ASCII 13, CR) wurde auch von fast jedem 8-Bit-Mikrocomputer vor dem Macintosh verwendet, einschließlich Apple II, Commodore und Atari. –

+0

Siehe meine Antwort für eine Frage zu Ihrer Antwort. –

0

Sie können versuchen, einen Generator Ansatz zu verwenden, um die Linien selbst zu lesen und alle EOL Zeichen ignorieren:

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

Hoppla, habe gerade den Post von bgporter bemerkt - wenn es eine native Unterstützung dafür gibt, dann brauchst du diesen Generator offenbar nicht. :) – Kos

+0

Ihre Lösung verwirft leere Zeilen (zB '\ n \ n' oder' \ r \ n \ r \ n'), liefert Zeichenlisten anstelle von Strings und wird sehr langsam ausgeführt, weil Sie jeweils ein Zeichen ohne gelesen haben Pufferung. Ich bin mir nicht sicher, ob die Arbeit mit Zeichenlisten anstelle von Zeichenfolgen die Leistung verbessert. –

Verwandte Themen