¡Hola a todos! En el artículo de hoy, veremos el uso del módulo IO de Python.
Este módulo es bastante útil cuando se quieren realizar operaciones de E/S relacionadas con archivos (Ej. lectura/escritura de archivos)
Aunque puedes utilizar los métodos normales read()
y write()
para leer/escribir en un archivo, este módulo nos da mucha más flexibilidad en cuanto a estas operaciones.
Para entender mejor este módulo, vamos a poner algunos ejemplos.
Módulo IO de Python
Este módulo forma parte de la librería estándar, por lo que no es necesario instalarlo por separado usando pip.
Para importar el módulo io, podemos hacer lo siguiente:
import io
En el módulo io
hay 2 clases comunes que nos son muy útiles:
- BytesIO -> Operaciones de E/S sobre datos de bytes
- StringIO -> Operaciones de E/S sobre datos de cadenas
Podemos acceder a estas clases utilizando io.BytesIO
y io.StringIO
.
Vamos a verlas una a una.
Clase BytesIO de Python
Aquí podemos guardar nuestros datos en forma de bytes (b''
). Cuando usamos io.BytesIO
, los datos se mantienen en un buffer en memoria.
Podemos obtener una instancia al flujo de bytes usando el constructor:
import iobytes_stream = io.BytesIO(b'Hello from Journaldev\x0AHow are you?')
Nota que estamos pasando una cadena de bytes (prefijada usando b
).
Ahora mismo, bytes_stream
es simplemente un manejador del flujo de bytes.
Para imprimir realmente los datos dentro del buffer, necesitamos usar bytes_stream.getvalue()
.
import iobytes_stream = io.BytesIO(b'Hello from Journaldev\x0AHow are you?')print(bytes_stream.getvalue())
Aquí, getvalue()
toma el valor de la cadena de bytes del handle.
Como la cadena de bytes \x0A
es la representación ASCII de la nueva línea (‘\n’), obtenemos la siguiente salida:
Salida
b'Hello from Journaldev\nHow are you?'
Ahora bien, siempre es una buena práctica cerrar el handle de nuestro buffer cuando hayamos terminado nuestro trabajo.
Esto también es para asegurarnos de que liberamos la memoria que hayamos asignado al buffer.
Para cerrar el buffer, utiliza:
bytes_stream.close()
Ahora veamos la clase StringIO.
Clase StringIO de Python
De forma similar a io.BytesIO
, la clase io.StringIO
puede leer datos relacionados con cadenas de un buffer StringIO.
import iostring_stream = io.StringIO("Hello from Journaldev\nHow are you?")
Podemos leer del buffer de cadenas usando string_stream.read()
y escribir usando string_stream.write()
. ¡Esto es muy similar a la lectura/escritura de un archivo!
Podemos imprimir el contenido usando getvalue()
.
Salida
Initially, buffer: Hello from JournaldevHow are you?Finally, buffer: This will overwrite the old content of the buffer if the length of this string exceeds the old content
¡Dado que estamos escribiendo en el mismo buffer, el nuevo contenido obviamente sobrescribirá el anterior!
Lectura de un buffer StringIO
De forma similar a la escritura, también podemos leer de un buffer StringIO utilizando buffer.read()
.
import ioinput = io.StringIO('This goes into the read buffer.')print(input.read())
Salida
This goes into the read buffer.
Como puedes ver, el contenido está ahora dentro del buffer de lectura, que se imprime usando buffer.read()
.
Leyendo un archivo usando io
Podemos usar el método io.open()
para leer directamente de un archivo también, de forma similar a la lectura de un objeto archivo.
Aquí, este módulo nos da la opción de lectura con buffer o sin buffer.
Por ejemplo, lo siguiente utilizará una lectura con buffer para leer un archivo, poniendo buffering = SIZE
. Si SIZE
= 0, ¡esto implicará que no hay búfer!
Supongamos que sample.txt
tiene el siguiente contenido:
Hello from JournalDev!How are you?This is the last line.
Salida
b'Hello from JournalDev!\nHow are you?\nThis is the last line.\n'
¡Como puedes ver, el archivo se ha leído con éxito! Aquí, io
leerá el archivo usando un tamaño de búfer de aproximadamente 5 bytes.
Usando io.open() vs os.open()
La función io.open() es una forma muy preferida de realizar operaciones de E/S ya que está hecha como una interfaz pitónica de alto nivel.
Por el contrario, el os.open()
realizará una llamada al sistema a la función open()
. Esto devolverá un descriptor de archivo, que no puede ser utilizado como el objeto io
handle.
Dado que io.open()
es una función envolvente de os.open()
, generalmente es una buena práctica utilizar dichas funciones envolventes, ya que manejan automáticamente muchos errores por ti.
Conclusión
En este artículo, hemos aprendido a utilizar el módulo IO de Python, y sus dos clases principales – io.BytesIO
y io.StringIO
para leer y escribir datos de bytes y cadenas en un buffer.