2.2 · Cadenas, formato (f-strings) y archivos

Nivel 2 · Estructuras de datos y POO

2.2Cadenas, formato (f-strings) y archivos

Objetivo: Formatear texto y leer/escribir archivos (txt, CSV, JSON).
Tiempo estimado: 14 min · lectura autónoma · Si solo tienes 5 min: lee «Lo esencial en 30s» + el esquema.

Lo esencial en 30 segundos

  • f-strings en todas partes: f"...{var}..." legible, rápido, con formato integrado (:.2f, :.0%) — olvidar % y .format() fuera de legacy.
  • split divide, join une, strip limpia: el trío que transforma el texto — in comprueba la presencia.
  • with lo cierra solo: with open(..., encoding="utf-8") + json/csv + pathlib — sus programas conservan memoria.

Minicaso hilado — Nabil redacta el informe mensual

Nabil debe enviar el informe mensual de ventas de Argel: montos formateados con dos decimales, nombres limpiados (espacios, mayúsculas), líneas CSV divididas y reunidas. Su primera versión concatena con + y olvida cerrar sus archivos — acentos rotos, archivo bloqueado. Lo reconstruye: f-strings con :.2f para los totales, strip/lower/split/join para limpiar, with open(..., encoding="utf-8") para leer/escribir, JSON para que la agenda persista entre dos ejecuciones. En 2.3, estas líneas se convertirán en objetos; en 2.4, el archivo ausente se gestionará correctamente.

Continuación del hilo 2.1: las ventas de Nabil se convierten en un informe legible y persistente — y continúa en 2.3 y 2.4.

1. Los f-strings: la única forma moderna

f"Hola {nombre}, total: {total:.2f} €": legible, rápido, con formato integrado (f"{precio:.2f} €", f"{ratio:.0%}"). La variable o el cálculo se inserta directamente entre llaves — sin conversión manual, sin error de tipo. Olvide % y .format() fuera del código antiguo: el f-string es el estándar desde Python 3.6. Nabil lo aplica: cada línea del informe mensual es un f-string con montos de dos decimales y porcentajes calculados al vuelo.

2. Métodos que rentan: split, join, strip

"Argel, Orán, Blida".split(", ") divide en lista, ", ".join(lista) une (el inverso exacto), .strip() limpia los espacios de las entradas, .lower() y .replace() normalizan. .upper() muestra, in comprueba la presencia (if "@" in email:). Estos métodos no modifican la cadena de origen (las cadenas son inmutables): devuelven una nueva cadena. Nabil limpia así cada nombre de cliente (strip().title()) antes de compararlo — se acabaron los duplicados «argel» frente a «Argel».

3. Archivos: with, encoding, JSON

with open("ventas.txt", encoding="utf-8") as f: — el with lo cierra solo incluso en caso de error, y el encoding="utf-8" evita los acentos rotos. Los modos: "r" lee (defecto), "w" escribe sobrescribiendo, "a" añade al final. Para estructurar: json.load/dump (listas y dicts persistentes — la agenda sobrevive al reinicio), módulo csv para las hojas de cálculo, pathlib.Path para rutas limpias sin concatenación. Nabil guarda su resumen en JSON con ensure_ascii=False para mantener los acentos legibles.

Error frecuente de interpretación: «Concatenar con + y abrir sin with funciona igual de bien». No. La concatenación con + es ilegible en cuanto se mezcla texto y números (y provoca TypeError sin conversión), sin formato integrado; open() sin with deja el archivo abierto en caso de error (fuga, bloqueo) y sin encoding rompe los acentos. La regla de Nabil: f-string para mostrar, split/join/strip para transformar, with + encoding para conservar — tres gestos, cero sorpresas.
Texto y archivos Mostrar, transformar, conservar f-string (mostrar) Variablesy :.2f integradossplit/join (transformar) Dividir,unir, limpiarwith+JSON (conservar) Cierrasolo, encoding, persistente
Mostrar, transformar, conservar
Versión en texto del esquema (SEO / lectores de pantalla / traducción): 1) Nabil MUESTRA con f-strings: variables y cálculos entre llaves, :.2f para los montos, :.0% para las partes — ni % ni concatenación. 2) TRANSFORMA con split (dividir), join (unir), strip/lower/replace (limpiar, normalizar) e in para comprobar. 3) CONSERVA con with open(..., encoding="utf-8") que lo cierra solo, modos r/w/a distinguidos, JSON para estructurar y pathlib para las rutas. Lección: mostrar, transformar, conservar — con las herramientas modernas.

🔎 Ejemplo concreto — 🔎 Ejemplo concreto — La agenda persistente de Nabil en JSON

El resumen sobrevive al reinicio, como en casa de Nabil:

import json
from pathlib import Path
fichero = Path("recap.json")
if fichero.exists():
    resumen = json.loads(fichero.read_text(encoding="utf-8"))
else:
    resumen = []
resumen.append({"wilaya": "Argel", "total": 1650})
fichero.write_text(json.dumps(resumen, ensure_ascii=False, indent=2), encoding="utf-8")
print(f"Wilayas seguidas: {len(resumen)}")

Lectura: pathlib verifica la existencia, json carga y guarda, el f-string muestra.

Lección: pathlib sustituye las concatenaciones de rutas.

Vocabulario de la sección

Métodos de cadena
Funciones ligadas al texto: .upper(), .lower(), .strip() (espacios), .split() (divide), .join() (une), .replace(). Devuelven una nueva cadena.

Ejemplo sencillo: Nabil limpia un nombre con nombre.strip().title().

Lo que no es: unas funciones que modifican la cadena in situ.

Reflejo: transformar texto = método devuelto.

f-string
Cadena con prefijo f donde {variable} se sustituye por su valor: f"Hola {nombre}". Formato integrado (:.2f, :.0%). Método recomendado desde Python 3.6.

Ejemplo sencillo: Nabil escribe f"Total: {total:.2f} €".

Lo que no es: una concatenación con + y str() por todas partes.

Reflejo: mostrar valores = f-string.

with open()
Abre un archivo garantizando su cierre automático: with open("f.txt", encoding="utf-8") as f:. Modos r (lee), w (sobrescribe), a (añade).

Ejemplo sencillo: Nabil lee la exportación con with y encoding utf-8.

Lo que no es: un open() sin with ni encoding.

Reflejo: archivo = with + encoding, siempre.

CSV
Archivo de texto donde los valores están separados por comas: formato de intercambio universal (hojas de cálculo). Módulo csv para leer/escribir correctamente.

Ejemplo sencillo: Nabil divide cada línea de exportación con el módulo csv.

Lo que no es: un recorte manual que se rompe con las comillas.

Reflejo: hoja para intercambiar = módulo csv.

JSON
Formato de texto estructurado (claves/valores) universal para los datos y las API. Módulo json: json.load / json.dump, listas y dicts persistentes.

Ejemplo sencillo: El resumen de Nabil sobrevive al reinicio en JSON.

Lo que no es: un archivo de texto improvisado ilegible para otras herramientas.

Reflejo: estructurado para conservar = JSON.

En la práctica — En práctica — Formatear texto y leer/escribir archivos

  1. Limpie y transforme una cadena: " informe argel ".strip().upper(), y luego divida una línea CSV en campos con .split().
  2. Componga una línea de informe con un f-string que incluya un cálculo: f"Total: {precio * cantidad:.2f} €" (2 decimales).
  3. Escriba texto con «with open("notas.txt", "w", encoding="utf-8") as f» y luego reléalo en modo «r»: verifique el cierre automático.
  4. Cargue/guarde una lista de dicts en JSON con json.dump y json.load: constate la persistencia entre dos ejecuciones.
Formatea correctamente el texto con los f-strings y lee/escribe archivos txt, CSV y JSON: sus programas conservan memoria.

Script listo para decir — explicar with a un colega (30 s)

«Para el informe de Nabil, todo pasa por f-strings con :.2f — nada de concatenación. Y cada archivo se abre con with y encoding utf-8: se cierra solo aunque falle, y los acentos de Argel quedan intactos. El resumen va en JSON, sobrevive al reinicio.»

Para decir mostrando un archivo bloqueado sin with, y luego limpio con with.

Modelo copiar-pegar — informe formateado y guardado JSON

import json
from pathlib import Path
lineas = ["  argel,1650 ", "orán,800", " argel,450 "]
total = 0.0
for linea in lineas:
    wilaya, monto = [c.strip() for c in linea.split(",")]
    total += float(monto)
    print(f"{wilaya.title():<10} : {float(monto):.2f} €")
print(f"{'Total':<10} : {total:.2f} €")
Path("total.json").write_text(json.dumps({"total": total}, ensure_ascii=False, indent=2), encoding="utf-8")

Línea de informe

Cada venta de Nabil se convierte en f"{wilaya}: {monto:.2f} €" — cálculo y formato en una línea.

Nombres para normalizar

Las wilayas introducidas a granel pasan por strip().lower(): «Argel» y «argel» ya no duplican.

Exportación CSV para releer

La exportación del mes se divide en split/join vía el módulo csv: campos y comillas gestionados correctamente.

Resumen para conservar

El total mensual va en JSON con ensure_ascii=False: acentos intactos, releído al mes siguiente.

✓ Buenas prácticas

  • Usar los f-strings en todas partes, con formato integrado (:.2f, :.0%).
  • Limpiar sistemáticamente las entradas (strip, lower) antes de comparar.
  • Abrir con with + encoding y preferir pathlib + JSON para persistir.

✗ Errores frecuentes

  • Concatenar con + en lugar de un f-string (ilegible, errores de tipo).
  • Abrir sin with (archivo no cerrado en caso de error).
  • Olvidar encoding="utf-8" (acentos rotos) o abrir en "w" un archivo para conservar (sobrescrito).

Puntos clave

  • Los métodos de cadena (upper, strip, split, join, replace) transforman el texto (nueva cadena devuelta).
  • Los f-strings (f"...{var}...") son la forma moderna y legible de formatear, con :.2f y :.0%.
  • with open(..., encoding="utf-8") lee/escribe cerrando automáticamente; r lee, w sobrescribe, a añade.
  • CSV y JSON son los formatos de intercambio (módulos csv y json); pathlib para las rutas.

Desafío 48h — aplíquelo mañana

Tome un archivo de texto real (el de Nabil o el suyo): límpielo (strip/split/join), muestre un resumen en f-strings con :.2f, guárdelo en JSON vía with + encoding y reléalo tras reiniciar.

Lista de salida de la sección
  • Puedo formatear con f-strings (variables, cálculos, :.2f).
  • Sé limpiar con strip/split/join y comprobar con in.
  • He leído y escrito un archivo con with + encoding, y persistido en JSON.
Autoevaluación 1-5: ¿uso los f-strings en lugar de +?¿cada open() está en with con encoding?

Preguntas frecuentes

¿Por qué preferir los f-strings a la concatenación con +?

Los f-strings son más legibles, evitan los errores de tipo (sin necesidad de convertir los números en str) y permiten el formato integrado (:.2f para 2 decimales, alineación, porcentajes). Es el método recomendado oficialmente desde Python 3.6.

¿Qué diferencia hay entre los modos «r», «w» y «a» de open()?

«r» lee (por defecto), «w» escribe BORRANDO el contenido existente, «a» añade al final (append) sin borrar. Atención: abrir un archivo existente en «w» elimina su contenido de inmediato — de ahí el interés de releer antes de escribir.

Comprueba tu comprensión

¿Qué garantiza el bloque «with open(...)»?

Recursos adicionales (opcional, para ir más allá)

Examen del nivel 2Preguntas inéditas y más difíciles para validar tus conocimientos