Diferencia entre analizar un archivo de texto en modo r y rb

¿Qué hace que analizar un archivo de texto en modo 'r' sea más conveniente que analizarlo en modo 'rb'? Especialmente cuando el archivo de texto en cuestión puede contener caracteres no ASCII.

preguntado el 10 de marzo de 12 a las 05:03

¿Estás leyendo un archivo de texto o un archivo binario? -

Un archivo de texto. Pero por alguna razón, recibo el archivo como un flujo de bytes. -

4 Respuestas

Esto depende un poco de la versión de Python que estés usando. En Python 2, La respuesta de Chris Drappier aplica.

En Python 3, es una historia diferente (y más consistente): en modo texto ('r'), Python analizará el archivo de acuerdo con la codificación de texto que le proporcione (o, si no le da una, una predeterminada dependiente de la plataforma), y read() le dará una str. En binario ('rb'), Python no asume que el archivo contiene cosas que razonablemente pueden ser analizadas como caracteres, y read() le da una bytes objeto.

Además, en Python 3, las nuevas líneas universales (la traducción entre '\n' y convenciones de nueva línea específicas de la plataforma para que no tenga que preocuparse por ellas) está disponible para archivos en modo texto en cualquier plataforma, no solo Windows.

contestado el 23 de mayo de 17 a las 13:05

para py3, ¿la lectura en modo texto intentará detectar automáticamente qué tipo de codificación es? Me imagino que tener que detectar la codificación es todo un desafío con un objeto de bytes. - MXLDevs

@Keikoku Es imposible detectar la codificación basada solo en un flujo, sin metadatos; piense en las diversas codificaciones que son ASCII + use el octavo bit para obtener información en lugar de paridad; todos comparten 8 secuencias válidas de un byte, pero solo la mitad de ellas (la mitad ASCII) representan el mismo carácter en cada una. El valor predeterminado de Python no es adivinarlo, es una codificación predeterminada de toda la sesión, deletreada sys.getdefaultencoding(). En mi instalación de Py3, es UTF-8, pero no puedes confiar en que siempre sea así. - lvc

from the documentación:

En Windows, la 'b' agregada al modo abre el archivo en modo binario, por lo que también hay modos como 'rb', 'wb' y 'r + b'. Python en Windows hace una distinción entre archivos de texto y binarios; los caracteres de final de línea en archivos de texto se modifican ligeramente automáticamente cuando se leen o escriben datos. Esta modificación detrás de escena de los datos de archivo está bien para los archivos de texto ASCII, pero corromperá los datos binarios como ese en los archivos JPEG o EXE. Tenga mucho cuidado de utilizar el modo binario al leer y escribir dichos archivos. En Unix, no está de más agregar una 'b' al modo, por lo que puede usarlo independientemente de la plataforma para todos los archivos binarios.

respondido 10 mar '12, 05:03

Entonces, básicamente, tratar de leer líneas en modo binario es mucho más difícil porque no tengo garantía de que el carácter EOL sea \ n o \ r \ n o algo más. - MXLDevs

La diferencia radica en cómo se maneja el final de línea (EOL). Los diferentes sistemas operativos usan diferentes caracteres para marcar el EOL - \n en Unix, \r en versiones de Mac anteriores a OS X, \r\n en Windows. Cuando se abre un archivo en modo texto, cuando se lee el archivo, Python reemplaza el carácter de fin de línea específico del sistema operativo leído del archivo con solo \n. Y viceversa, es decir, cuando intentas escribir \n a un archivo abierto en modo texto, escribirá el carácter EOL específico del sistema operativo. Puede encontrar cuál es el EOL predeterminado de su sistema operativo marcando os.linesep.

Cuando se abre un archivo en modo binario, no se realiza ningún mapeo. Lo que lees es lo que obtienes. Recuerde, el modo de texto es el modo predeterminado. Entonces, si está manejando archivos que no son de texto (imágenes, video, etc.), asegúrese de abrir el archivo en modo binario; de lo contrario, terminará arruinando el archivo al introducir (o eliminar) algunos bytes.

Python también tiene un modo de nueva línea universal. Cuando se abre un archivo en este modo, Python asigna todos los caracteres \r, \n y \r\n a \n.

Respondido 04 Oct 16, 00:10

¿Es esto cierto tanto para Python 2 como para Python 3? - Agustín

Para aclarar y responder. Comentario / pregunta de Agostino (No tengo suficiente reputación para comentar, así que tengan paciencia si digo esto como una respuesta ...):

En Python 2 no se produce ninguna modificación al final de la línea, ni en modo texto ni en modo binario, como se ha dicho antes, en Python 2 La respuesta de Chris Drappier se aplica (tenga en cuenta que su enlace ahora apunta a los documentos de Python 3.x, pero el texto citado de Chris es, por supuesto, del Tutorial de entrada y salida de Python 2)

Entonces no, es no cierto que abrir un archivo en texto modo con Python 2 en no Windows hace alguna modificación al final de la línea:

0 $ cat data.txt 
line1
line2
line3
0 $ file data.txt 
data.txt: ASCII text, with CRLF line terminators
0 $ python2.7 -c 'f = open("data.txt"); print f.readlines()'
['line1\r\n', 'line2\r\n', 'line3\r\n']
0 $ python2.7 -c 'f = open("data.txt", "r"); print f.readlines()'
['line1\r\n', 'line2\r\n', 'line3\r\n']
0 $ python2.7 -c 'f = open("data.txt", "rb"); print f.readlines()'

Sin embargo, es posible abrir el archivo en modo de nueva línea universal en Python 2, que realiza exactamente dicho mod de fin de línea:

0 $ python2.7 -c 'f = open("data.txt", "rU"); print f.readlines()'
['line1\n', 'line2\n', 'line3\n']

(el especificador del modo de nueva línea universal está obsoleto a partir de Python 3.x)

En Python 3, por otro lado, los extremos de línea específicos de la plataforma se normalizan a '\ n' cuando se lee un archivo en modo texto, y '\ n' se convierte al final de línea predeterminado de la plataforma actual cuando se escribe en modo texto ( además de los bytes <-> unicode <-> bytes de decodificación / codificación en modo texto). Por ejemplo, leer un archivo de línea CRLF Dos / Win en Linux normalizará los extremos de línea a '\ n'.

Respondido 25 Jul 17, 08:07

La función abierta de Python3 tiene un parámetro de nueva línea para controlar eso si es necesario docs.python.org/3/library/functions.html#open "newline controla cómo funciona el modo universal de nuevas líneas (solo se aplica al modo de texto). Puede ser None, '', '\ n', '\ r' y '\ r \ n'. Funciona de la siguiente manera: Al leer entrada de la secuencia, si la nueva línea es Ninguna, el modo de nuevas líneas universal está habilitado "- Davos

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.