Las f-strings permiten insertar valores dentro de textos y controlar su presentación con una sintaxis compacta. Son especialmente útiles para mostrar precios, porcentajes, medidas, fechas y cantidades grandes. El valor numérico no cambia: únicamente cambia la cadena que se presenta al usuario. Esta separación evita mezclar la lógica de cálculo con el formato visual.
Antes de empezar, resulta útil repasar las strings en Python, los números decimales, la entrada y salida, las funciones y el uso de diccionarios para organizar configuraciones.
Qué es una f-string
Una f-string comienza con la letra f antes de las comillas. Las expresiones que deben evaluarse se escriben entre llaves:
producto = "Teclado"
precio = 89.9
print(f"{producto}: {precio}")
El resultado es Teclado: 89.9. Para una presentación comercial normalmente queremos dos decimales:
print(f"{producto}: {precio:.2f}")
# Teclado: 89.90
La referencia oficial de f-strings explica cómo se evalúan las expresiones. La mini-lengua oficial de especificación de formato documenta alineación, anchura, precisión, signos y tipos numéricos.
Controlar el número de decimales
valor = 12.34567
print(f"{valor:.0f}") # 12
print(f"{valor:.1f}") # 12.3
print(f"{valor:.2f}") # 12.35
print(f"{valor:.4f}") # 12.3457
El sufijo f indica formato de punto fijo y el número después del punto define la precisión visible. El redondeo de presentación no modifica la variable:
original = 12.34567
texto = f"{original:.2f}"
print(original) # 12.34567
print(texto) # 12.35
Separadores de miles
poblacion = 12345678
facturacion = 9876543.21
print(f"{poblacion:,}")
print(f"{facturacion:,.2f}")
El formato estándar usa coma para separar miles y punto para decimales, siguiendo una convención frecuente en inglés. Si necesitas intercambiar los símbolos de manera controlada, no hagas reemplazos sucesivos sin un marcador temporal:
def formato_es(valor: float) -> str:
base = f"{valor:,.2f}"
return base.replace(",", "_").replace(".", ",").replace("_", ".")
print(formato_es(1234567.89))
# 1.234.567,89
Esta función sirve para una interfaz sencilla. Para internacionalización completa, utiliza una biblioteca de locales como Babel, porque las reglas varían por país y moneda.
Mostrar símbolos monetarios
precio = 1499.5
print(f"€ {precio:,.2f}")
print(f"US$ {precio:,.2f}")
print(f"R$ {formato_es(precio)}")
El símbolo no convierte la moneda. Solo etiqueta el valor. Para convertir euros a dólares necesitas una tasa de cambio y una operación separada.
Crear una función reutilizable
SIMBOLOS = {
"EUR": "€",
"USD": "US$",
"BRL": "R$",
}
def formatear_moneda(valor: float, codigo: str) -> str:
codigo = codigo.upper()
simbolo = SIMBOLOS.get(codigo, codigo)
numero = formato_es(valor)
return f"{simbolo} {numero}"
print(formatear_moneda(1999.9, "EUR"))
En aplicaciones internacionales es mejor conservar también el código ISO, porque símbolos como $ pueden representar monedas distintas.
Porcentajes
El especificador % multiplica visualmente por cien y añade el símbolo:
tasa = 0.1875
print(f"{tasa:.0%}") # 19%
print(f"{tasa:.1%}") # 18.8%
print(f"{tasa:.2%}") # 18.75%
No multipliques manualmente si usas este formato, porque obtendrías un porcentaje cien veces mayor.
Alinear columnas
productos = [
("Monitor", 1299.9),
("Cable HDMI", 35.5),
("Teclado mecánico", 289.0),
]
for nombre, precio in productos:
print(f"{nombre:<20} {precio:>10.2f}")
< alinea a la izquierda y > a la derecha. El número define la anchura mínima. Esto ayuda a crear reportes de terminal, aunque para tablas complejas conviene usar CSV, HTML o una biblioteca especializada.
Mostrar signos y rellenar con ceros
cambio = 15.4
perdida = -8.2
codigo = 42
print(f"{cambio:+.2f}") # +15.40
print(f"{perdida:+.2f}") # -8.20
print(f"{codigo:06d}") # 000042
El signo explícito es útil en informes de variación. El relleno con ceros puede servir para identificadores visuales, pero no debe cambiar el tipo real del dato almacenado.
Notación científica y compacta
pequeno = 0.000001234
muy_grande = 987654321
print(f"{pequeno:.2e}")
print(f"{muy_grande:.3g}")
e produce notación científica. g selecciona una representación compacta según la magnitud.
Decimal para dinero
Los floats binarios pueden producir pequeñas diferencias:
print(0.1 + 0.2)
# 0.30000000000000004
Para cálculos financieros utiliza Decimal y crea los valores desde strings:
from decimal import Decimal, ROUND_HALF_UP
precio = Decimal("19.90")
cantidad = Decimal("3")
total = precio * cantidad
total = total.quantize(Decimal("0.01"), rounding=ROUND_HALF_UP)
print(f"Total: € {total:.2f}")
La f-string presenta el resultado, mientras Decimal controla la aritmética y el redondeo.
Formato dependiente de la configuración regional
Los separadores, la posición del símbolo, los espacios y el número de decimales dependen del idioma y de la moneda. En una aplicación pequeña puedes definir funciones explícitas. En un sistema internacional, utiliza Babel:
from babel.numbers import format_currency
texto = format_currency(1234.5, "EUR", locale="es_ES")
print(texto)
No dependas ciegamente de la configuración regional del sistema operativo, porque puede no estar instalada en el servidor.
Depurar con el especificador igual
subtotal = 100
descuento = 0.15
print(f"{subtotal=}, {descuento=:.1%}")
Este formato es útil durante el desarrollo, pero no suele ser apropiado para mensajes finales dirigidos al usuario.
Evitar errores frecuentes
No confundas formato con conversión de moneda. No redondees cada paso intermedio sin una regla de negocio. No uses float para valores financieros críticos. No concatenes manualmente números sin convertirlos y no guardes valores monetarios ya formateados en la base de datos. Guarda el importe y el código como datos separados.
También debes validar valores especiales como NaN, infinito y campos ausentes antes de presentarlos. Una interfaz profesional debe decidir qué mostrar cuando el dato no está disponible.
Ejemplo completo de recibo
from decimal import Decimal
def crear_recibo(items, impuesto):
subtotal = sum(
Decimal(str(precio)) * cantidad
for _, precio, cantidad in items
)
tasa = Decimal(str(impuesto))
valor_impuesto = subtotal * tasa
total = subtotal + valor_impuesto
lineas = ["RECIBO", "-" * 40]
for nombre, precio, cantidad in items:
importe = Decimal(str(precio)) * cantidad
lineas.append(f"{nombre:<20} x{cantidad:<3} € {importe:>8.2f}")
lineas.extend([
"-" * 40,
f"{'Subtotal':<28} € {subtotal:>8.2f}",
f"{'Impuesto':<28} € {valor_impuesto:>8.2f}",
f"{'Total':<28} € {total:>8.2f}",
])
return "\n".join(lineas)
Conclusión
Las f-strings ofrecen una forma legible de presentar números, monedas, porcentajes y columnas. Utiliza precisión, anchura, alineación y separadores según el contexto. Mantén el cálculo separado del formato, usa Decimal para dinero y adopta una biblioteca de internacionalización cuando la aplicación atienda varios países. Así obtendrás salidas claras sin comprometer la precisión de los datos.






