2010-11-11 8 views
10

Estoy escribiendo un archivo de Python que necesita leer en varios archivos de diferentes tipos. Estoy leyendo los archivos en línea por línea con el for line in f tradicional después de usar f = open("file.txt", "r").¿Hace que el método readline de Python reconozca ambas variaciones al final de la línea?

Esto no parece funcionar para todos los archivos. Mi suposición es que algunos archivos terminan con diferentes codificaciones (como \ r \ n versus just \ r). Puedo leer todo el archivo y hacer una división de cadena en \ r, pero eso es muy costoso y prefiero no hacerlo. ¿Hay alguna manera de hacer que el método readline de Python reconozca ambas variaciones al final de la línea?

Respuesta

17

utilizar el soporte de nueva línea universal - ver http://docs.python.org/library/functions.html#open

Además de la fopen estándar() modo de valores puede ser 'T' o 'r M'. Python generalmente se construye con soporte universal newline; el suministro de 'U' abre el archivo como un archivo de texto, pero las líneas pueden terminar por cualquiera de los siguientes: convenio de finalización de línea '\ n', la convención '\ r' de Macintosh, o Convención de Windows '\ r \ n'. Todas estas representaciones externas son vistas como '\ n' por el programa Python. Si se construye Python sin universal compatibilidad con línea nueva un modo con 'U' es el igual que el modo de texto normal. Tenga en cuenta que los objetos de archivo así abiertos también tienen un atributo llamado newlines que tiene un valor Ninguno (si aún no se han visto nuevas líneas ), '\ n', '\ r', '\ r \ n' o una tupla que contiene todos los tipos de nueva línea visto.

+0

Por supuesto, la convención "Macintosh" de poner fin a la línea termina con '\ r' (ASCII 13, CR) también fue utilizado por casi todos los microordenadores de 8 bits anteriores al Macintosh, incluidos Apple II, Commodore y Atari. –

+0

Consulte mi respuesta para obtener una pregunta acerca de su respuesta. –

0

Usted puede tratar de utilizar un enfoque generador de leer las líneas por sí mismo e ignorar cualquier carácter 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

Vaya, acaba de notar la publicación de bgporter: si hay un soporte nativo para eso, entonces aparentemente no necesitará este generador. :) – Kos

+0

Su solución descarta líneas en blanco (por ejemplo, '\ n \ n' o' \ r \ n \ r \ n'), produce listas de caracteres en lugar de cadenas, y se ejecutará muy lentamente debido a la lectura de un carácter a la vez sin almacenamiento en búfer No estoy seguro de que trabajar con listas de caracteres en lugar de cadenas mejore el rendimiento tampoco. –

Cuestiones relacionadas