La forma correcta de cargar texto Unicode de Python 2.7 es algo así como:¿Cómo decodifico unicode una línea a la vez en Python 2.7?
content = open('filename').read().decode('encoding'):
for line in content.splitlines():
process(line)
(actualización: No, no es ver las respuestas..)
Sin embargo, si el archivo es muy grande, podría querer leer, decodificar y procesar una línea a la vez, de modo que el archivo completo nunca se cargue en la memoria de una vez. Algo así como:
for line in open('filename'):
process(line.decode('encoding'))
iteración El for
del aro sobre el gestor de archivo abierto es un generador que lee una línea a la vez.
Esto no funciona, porque si el archivo está codificado utf32, por ejemplo, entonces los bytes en el archivo (en hexadecimal) ser algo como:
hello\n = 68000000(h) 65000000(e) 6c000000(l) 6c000000(l) 6f000000(o) 0a000000(\n)
Y la división en líneas hechas por el bucle for
divide en la 0a
byte del carácter \n
, dando como resultado (en hexadecimal):
lines[0] = 0x 68000000 65000000 6c000000 6c000000 6f000000 0a
lines[1] = 0x 000000
Así que parte del carácter \n
se deja al final de la línea 1, y los tres bytes restantes terminan en línea 2 (seguido de cualquier texto que esté realmente en la línea 2). Llamar al decode
en cualquiera de estas líneas resulta comprensible en un UnicodeDecodeError
.
UnicodeDecodeError: 'utf32' codec can't decode byte 0x0a in position 24: truncated data
Así que, obviamente suficiente, la división de un flujo de bytes Unicode en 0a
bytes no es la forma correcta para dividirlo en líneas. En su lugar, debería dividir las apariciones del carácter de nueva línea completo de cuatro bytes (0x0a000000). Sin embargo, creo que la forma correcta de detectar estos caracteres es decodificar la secuencia de bytes en una cadena Unicode y buscar los caracteres \n
, y esta descodificación de la secuencia completa es exactamente la operación que trato de evitar.
Esto no puede ser un requisito poco común. ¿Cuál es la forma correcta de manejarlo?
¿Intentó leer el archivo utilizando el método codecs.open()? –
@Maulwurfn, ¡no sabía que existía! Pero ahora sí. Gracias. –