OPERACIONES SOBRE FICHEROS¶
Apertura y cierre de ficheros¶
La función open()¶
La función open() es el punto de entrada para trabajar con cualquier fichero en Python. Devuelve un objeto fichero con métodos para leer o escribir datos.
Su sintaxis básica es:
Los parámetros más importantes son:
ruta: cadena oPathcon la ubicación del ficheromode: modo de apertura (lectura, escritura, etc.) — por defecto"r"encoding: codificación de caracteres — se recomienda siempre indicarlo explícitamente
Modos de apertura¶
El parámetro mode controla qué operaciones se pueden realizar sobre el fichero y qué ocurre si este ya existe o no existe.
| Modo | Significado | ¿Crea el fichero? | ¿Borra contenido? |
|---|---|---|---|
"r" |
Lectura (por defecto) | No | No |
"w" |
Escritura | Sí | Sí |
"a" |
Añadir al final (append) | Sí | No |
"x" |
Creación exclusiva (error si ya existe) | Sí | — |
"r+" |
Lectura y escritura | No | No |
"b" |
Modo binario (se combina con los anteriores: "rb", "wb") |
— | — |
"t" |
Modo texto (por defecto, se puede omitir) | — | — |
Combinación de modos
Los modos se pueden combinar: "rb" abre en modo lectura binaria, "w+" permite leer y escribir borrando el contenido previo.
Cierre explícito con close()¶
Tras usar un fichero es obligatorio cerrarlo para liberar el recurso del sistema operativo y asegurar que los datos se escriben en disco.
El problema del cierre manual es que si ocurre una excepción entre la apertura y el close(), el fichero nunca se cierra:
El gestor de contexto with¶
Python proporciona el gestor de contexto with para garantizar que el fichero se cierre siempre, incluso si se produce un error:
El bloque with gestiona el ciclo de vida del fichero:
- Abre el fichero y lo asigna a la variable indicada tras
as - Ejecuta el bloque indentado
- Cierra el fichero siempre al salir del bloque, haya error o no
Usa siempre
withpara abrir ficheros. Es la forma recomendada en Python y evita errores difíciles de depurar relacionados con ficheros no cerrados.
Abrir varios ficheros a la vez¶
Se pueden abrir múltiples ficheros en un mismo with:
Codificación de caracteres¶
La codificación (encoding) determina cómo se convierten los caracteres a bytes y viceversa.
Si no se especifica, Python usa la codificación del sistema operativo, que varía entre plataformas. Esto provoca errores difíciles de reproducir, especialmente con caracteres especiales del español (tildes, ñ).
Usa siempre encoding=\"utf-8\"
UTF-8 es el estándar de facto en aplicaciones modernas. Soporta todos los caracteres del español y de prácticamente cualquier idioma. Si abres un fichero sin indicar encoding y el sistema del alumno o del servidor tiene otra configuración, obtendrás errores de codificación.
Antipatrón: abrir ficheros sin encoding ni with
Lectura de ficheros de texto¶
Para los ejemplos de esta sección usaremos el fichero notas.txt con el siguiente contenido:
El método read()¶
read() lee todo el contenido del fichero de una vez y lo devuelve como una única cadena de texto.
El texto devuelto por
read()incluye los saltos de línea\n. Si el fichero tiene 4 líneas, el string contendrá 3 caracteres\n(uno al final de cada línea, excepto posiblemente la última).
Se puede leer solo una parte del fichero indicando el número de caracteres:
El método readline()¶
readline() lee una sola línea cada vez que se llama, devolviendo la cadena incluyendo el \n del final.
Es útil cuando el fichero es muy grande y no interesa cargarlo entero en memoria:
Cuando se llega al final del fichero, readline() devuelve una cadena vacía "".
Este comportamiento permite leer el fichero completo en un bucle:
El método readlines()¶
readlines() lee todas las líneas de una vez y las devuelve como una lista de cadenas. Cada elemento de la lista incluye el \n del final.
Para trabajar con las líneas sin el \n se usa strip():
Iteración directa sobre el fichero¶
La forma más Pythónica y eficiente de leer un fichero línea a línea es iterar directamente sobre el objeto fichero. Python lo trata como un iterable de líneas:
Esta forma es la más recomendada para leer líneas: no carga todo el fichero en memoria y el código es muy legible.
Ejemplo: extraer nombres y notas¶
Usando la iteración directa, podemos procesar el fichero de notas para obtener la lista de alumnos:
Comparativa de métodos de lectura¶
| Método | Devuelve | Cuándo usarlo |
|---|---|---|
read() |
str con todo el contenido |
Ficheros pequeños, cuando necesitas todo el texto de una vez |
readline() |
str con una línea |
Cuando procesas el fichero secuencialmente y puede ser muy grande |
readlines() |
list de líneas |
Cuando necesitas acceder por índice a líneas concretas |
| Iteración directa | Línea a línea (más eficiente) | La opción recomendada para recorrer todas las líneas |
Antipatrón: usar read() en ficheros grandes
Escritura en ficheros de texto¶
El método write()¶
write() escribe una cadena de texto en el fichero y devuelve el número de caracteres escritos.
write()no añade el salto de línea automáticamente. Si quieres que cada llamada ocupe una línea distinta, debes añadir\nal final de cada cadena.
El resultado en el fichero notas.txt:
El método writelines()¶
writelines() escribe una lista de cadenas en el fichero, una tras otra. Al igual que write(), no añade saltos de línea automáticamente.
writelines()no añade saltos de línea entre elementos. Si los elementos de la lista no terminan en\n, todas las cadenas quedarán escritas seguidas en la misma línea.
Modo escritura "w" vs modo append "a"¶
La diferencia entre estos dos modos es fundamental:
Modo "w" — escritura¶
Abre el fichero para escribir. Si el fichero ya existe, borra todo su contenido antes de escribir. Si no existe, lo crea.
Modo "a" — append (añadir)¶
Abre el fichero para escribir al final del contenido existente. Si el fichero no existe, lo crea. Si existe, conserva lo que había.
Comparativa¶
| Modo | El fichero ya existe | El fichero no existe |
|---|---|---|
"w" |
Borra el contenido y escribe desde el principio | Lo crea |
"a" |
Escribe al final conservando el contenido | Lo crea |
Ejemplo: registro acumulativo de notas¶
Un caso de uso habitual de "a" es añadir registros a un fichero de log:
Cada vez que se ejecuta registrar_nota(), la línea se añade al final del fichero sin borrar las anteriores.
Uso de print() para escribir en ficheros¶
La función print() admite el parámetro file para redirigir la salida a un objeto fichero. Tiene la ventaja de añadir el salto de línea automáticamente:
Antipatrón: usar modo \"w\" sin querer borrar el contenido