Ficheros en python

Aunque ya había mirado como leer y escribir ficheros en python hace tiempo, con el tema del curso de python con el que estoy entretenido en la chuwiki, lo he estado revisando. Y ¿cómo no?, he encontrado un par de cosas que me han llamado la atención sólo porque son diferentes en java.

La primera es cómo saber si hemos llegado al final del fichero cuando hacemos un bucle para leerlo. En java, el método readLine() devuelve un null y hay que poner un if del estilo

while (null!=linea) {
   ...
}

En python, devuelve una cadena vacía. Esto es así porque el método readLine() de python devuelve los retornos de carro, así que una línea en blanco devolvería ‘\n’, mientras que en java devolvería una cadena vacía ». Y en python, para el bucle, tienes otra forma de hacerlo

while linea:
   ...

No hace falta compararlo con nada. Los condicionales de python son listos y si la cadena está vacía o es None, devuelve false. Aunque es diferente de java y me ha llamado la atención, este tipo de condicionales que dan false si la cadena está vacía o es None, no me ha llamado tanto la atención, puesto que javascript también funciona así.

Aquí sólo un apunte. En python me parece engorroso que al leer una línea me devuelva también el retorno de carro final. Java se lo come y no te lo devuelve. No sé qué es más útil, pero me da la impresión de que si la línea contiene campos que quieres extaer, estilo fichero CSV, el retorno de carro al final  vas a tener que eliminarlo con código.

Y lo segundo que me ha llamado mucho más la atención es que el descriptor de un fichero abierto de python es un iterator. Por lo que iterando sobre él vamos leyendo.  Podemos incluso meterlo en un bucle. En java, para leer un fichero hasta el final necesitamos algo tan engorroso coom esto

String linea = bufferedRead.readLine();
while (null!=linea) {
   // tratar la línea
   linea = bufferedReader.readLine();
}

es decir, dos lecturas, una antes de entrar en el bucle para tener la variable línea inicializada con la primera línea del fichero y luego, dentro del bucle, como última línea, otra lectura. Este tipo de estructuras siempre me ha parecido poco elegante por lo de hacer dos lecturas. Con un do-while tampoco podemos hacerlo con una lectura.

Sin embargo, en python, como el fichero abierto es un iterator, podemos hacer esto

f = open ('fichero.txt')
for linea in f:
   # Tratar la línea.

Mucho más claro. Funciona igual con ficheros de texto o binarios. Si lo abres como texto devuelve líneas, si lo tratas como binario devuelve bytes. Y ni siquiera hace falta la comparación para saber si hemos llegado a final de fichero.

Punto para python 🙂

ACTUALIZACION: Tras el comentario de GreenEyed, actualizo el post. No es necesario poner dos líneas de lectura en el código java «tradicional», basta con meterlo todo en el paréntesis del while

String line;
while ( (line = bufferedReader.readLine()) != null) {
   // tratar línea
}

y a partir de java 8 hay más opciones para leer el fichero como se ve en el enlace que pone en el comentario.

Esta entrada ha sido publicada en java, python y etiquetada como , , . Guarda el enlace permanente.

2 respuestas a Ficheros en python

  1. GreenEyed dijo:

    Por romper una lanza en favor de Java, desde Java 8, que ya tiene años, hay formas de leer ficheros linea a linea sin tener que hacer la doble lectura. Aquí mismo (https://mkyong.com/java8/java-8-stream-read-a-file-line-by-line/) hay varias formas de hacerlo, comparadas con las clásicas formas de hacerlo con varias lecturas.

    Así que ya solo queda sobre eso el tratamiento de excepciones/cerrar el Stream para no tener un leak :P.

    Un saludo

  2. Chuidiang dijo:

    Cierto, me he quedado anclado en el pasado.

    Es más, en el enlace que me has pasado, el punto «4. Classic BufferedReader and Scanner», ni siquiera hay que irse a cosas «modernas» de java 8 🙂

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.