textwrap en Python: formatea textos

Publicado el: 10/08/2026
Tempo de leitura: 5 minutos
Editor de texto que representa formato con textwrap en Python

El módulo textwrap de la biblioteca estándar formatea párrafos para terminales, informes, logs, mensajes, documentación e interfaces basadas en texto. Ajusta líneas a un ancho, añade sangrías, acorta textos por palabras y elimina el margen común de cadenas multilínea. Así evita funciones manuales frágiles y centraliza las reglas de presentación.

Esta guía explica wrap(), fill(), shorten(), dedent(), indent() y TextWrapper, incluyendo Unicode, palabras largas, guiones, párrafos y rendimiento.

Dividir un párrafo con wrap

wrap() recibe un único párrafo y devuelve una lista de líneas sin saltos finales.

import textwrap

texto = "Python permite crear herramientas claras para automatizar tareas repetitivas."
lineas = textwrap.wrap(texto, width=24)
print(lineas)

El ancho se mide en caracteres de Python, no en píxeles ni columnas visuales reales. Emojis, marcas combinantes y caracteres asiáticos pueden ocupar un espacio distinto en pantalla.

Crear una cadena lista con fill

fill() equivale a unir el resultado de wrap() con saltos de línea. Es la opción más cómoda para imprimir o guardar un párrafo.

formateado = textwrap.fill(texto, width=40)
print(formateado)

Ambas funciones aceptan las mismas opciones: sangrías, tratamiento de palabras largas, guiones, espacios, número máximo de líneas y placeholder.

Sangría inicial y colgante

initial_indent se aplica a la primera línea. subsequent_indent se aplica a las demás y cuenta dentro del ancho.

salida = textwrap.fill(
    texto,
    width=44,
    initial_indent="* ",
    subsequent_indent="  ",
)
print(salida)

Este patrón funciona bien en listas, ayudas de CLI, correo en texto plano e informes. Elige la anchura considerando el prefijo.

Acortar por palabras

shorten() primero colapsa todos los espacios y después elimina palabras del final hasta que el texto y el placeholder quepan.

resumen = textwrap.shorten(
    "Una descripción muy larga para una tarjeta pequeña",
    width=32,
    placeholder="...",
)
print(resumen)

La función evita cortar arbitrariamente dentro de palabras normales. El placeholder debe caber. Si necesitas conservar espacios originales, aplica otra política.

Eliminar la sangría común con dedent

Las cadenas triples dentro de funciones heredan la sangría del código. dedent() elimina el margen común y conserva la estructura relativa.

def mensaje():
    texto = """
        Hola,
          este elemento sigue sangrado.
        Hasta pronto.
    """
    return textwrap.dedent(texto).strip()

Tabs y espacios son whitespace, pero no equivalen como sangría. Mezclarlos puede impedir el resultado esperado. Python 3.14 mejoró la normalización de líneas vacías que contienen otros caracteres de espacio.

Añadir prefijos con indent

indent() añade un prefijo a las líneas no vacías por defecto. Un predicado opcional controla cuáles lo reciben.

bloque = "primera\n\nsegunda"
print(textwrap.indent(bloque, "> "))

todas = textwrap.indent(bloque, "+ ", lambda linea: True)

Es útil para citas, logs, comentarios, mensajes reenviados y bloques de código. El predicado recibe la línea con su terminador cuando existe.

Palabras mayores que el ancho

Por defecto, break_long_words=True permite dividir un token largo para respetar la anchura. Esto puede ser malo para URLs, hashes, identificadores y comandos.

salida = textwrap.fill(
    "identificador_extremadamente_largo_sin_espacios",
    width=20,
    break_long_words=False,
)
print(salida)

Si la división está desactivada, una línea puede superar el ancho. Decide si importa más conservar el token o el diseño.

Comportamiento con guiones

break_on_hyphens=True permite preferir saltos después de guiones. El comportamiento sigue convenciones orientadas al inglés y puede no ser adecuado para todos los idiomas o identificadores técnicos.

Para tokens indivisibles, establece break_on_hyphens=False y break_long_words=False.

Tabs y otros espacios

expand_tabs=True expande tabs usando tabsize. Después, replace_whitespace=True sustituye tab, newline, tab vertical, form feed y carriage return por espacios simples.

Si desactivas el reemplazo, los saltos internos pueden producir resultados extraños. Divide el contenido en párrafos antes de ajustarlo.

Un párrafo por vez

wrap() y fill() están diseñados para un único párrafo. Separa documentos largos y conserva explícitamente las líneas vacías.

def formatear_documento(texto, ancho=70):
    bloques = texto.split("\n\n")
    return "\n\n".join(
        textwrap.fill(bloque, width=ancho)
        for bloque in bloques
        if bloque.strip()
    )

Documentos con listas, títulos, tablas o bloques de código requieren un parser más estructurado.

Limitar el número de líneas

max_lines y placeholder crean vistas previas compactas.

vista = textwrap.fill(
    texto_largo,
    width=50,
    max_lines=2,
    placeholder=" [...]",
)

El placeholder participa en el cálculo. Prueba anchuras pequeñas y traducciones, porque un texto localizado más largo puede no caber.

Reutilizar TextWrapper

Las funciones de conveniencia crean una instancia en cada llamada. Reutiliza TextWrapper cuando formatees muchos textos con la misma configuración.

wrapper = textwrap.TextWrapper(
    width=60,
    subsequent_indent="  ",
    break_long_words=False,
)

for parrafo in parrafos:
    print(wrapper.fill(parrafo))

La instancia es mutable. Evita compartirla entre threads si las opciones cambian durante el uso. Una configuración fija por worker es más sencilla.

Unicode y anchura visual

textwrap cuenta caracteres de la cadena. Los terminales pueden mostrar caracteres CJK en dos columnas, acentos combinantes sin columna adicional y secuencias de emoji como un único símbolo visible.

Cuando necesites alineación visual exacta, combina una biblioteca de ancho de terminal con la política de ajuste. No supongas que len() equivale a columnas.

HTML y Markdown

Ajustar HTML o Markdown sin analizar puede dividir etiquetas, enlaces, tablas y fences de código. Usa un parser o procesa solo nodos de texto conocidos.

En navegador, el diseño depende de CSS y del ancho disponible. Una cantidad fija de caracteres no sustituye un layout responsive.

Ejemplo: ayuda de línea de comandos

def ayuda(titulo, descripcion):
    cabecera = textwrap.dedent(f"""
        {titulo}
        {'=' * len(titulo)}
    """).strip()
    cuerpo = textwrap.fill(
        descripcion,
        width=72,
        initial_indent="  ",
        subsequent_indent="  ",
        break_long_words=False,
    )
    return f"{cabecera}\n{cuerpo}"

El ejemplo separa la estructura de la cabecera y el párrafo, y conserva identificadores largos.

Errores frecuentes

  • Pasar varios párrafos como uno solo.
  • Esperar anchura visual exacta para cualquier Unicode.
  • Dividir URLs e identificadores sin querer.
  • Mezclar tabs y espacios antes de dedent().
  • Esperar que shorten() conserve espacios.
  • Compartir un wrapper mutable entre threads.
  • Formatear HTML o Markdown como texto plano.

Buenas prácticas

  • Elige el ancho para una superficie concreta.
  • Formatea párrafos por separado.
  • Conserva tokens largos cuando sea necesario.
  • Prueba placeholders traducidos.
  • Usa dedent().strip() en cadenas triples.
  • Reutiliza TextWrapper en lotes grandes.
  • Separa formato textual de diseño visual.

Guías relacionadas

Continúa con difflib en Python, locale en Python, pydoc en Python, fileinput en Python y linecache en Python.

Consulta la documentación oficial de textwrap y la documentación de strings.

Conclusión

textwrap ofrece una API completa para presentar texto en entornos con ancho limitado. Su uso correcto exige separar párrafos, definir una política para tokens largos y entender que el número de caracteres no siempre coincide con la anchura visual.

Compartilhe:

Facebook
WhatsApp
Twitter
LinkedIn

Contenido del artículo

    Artículos relacionados

    Carpeta y lupa que representan filtros de nombres con fnmatch en Python
    Bibliotecas y Módulos
    Foto de perfil de Leandro Hirt da Academify

    fnmatch en Python: filtra nombres de archivos

    Aprende fnmatch en Python para filtrar nombres de archivos con comodines, controlar mayúsculas, excluir patrones y distinguir glob de regex.

    Ler mais

    Tempo de leitura: 5 minutos
    10/08/2026
    Monitor con datos binarios que representa arrays numéricos compactos en Python
    Bibliotecas y Módulos
    Foto de perfil de Leandro Hirt da Academify

    array en Python: números compactos

    Aprende array en Python para almacenar números compactos, usar archivos binarios, byte order, memoryview y buffers seguros.

    Ler mais

    Tempo de leitura: 5 minutos
    10/08/2026
    Círculo cromático que representa conversiones RGB, HSV y HLS con colorsys en Python
    Bibliotecas y Módulos
    Foto de perfil de Leandro Hirt da Academify

    colorsys en Python: RGB, HSV y HLS

    Aprende colorsys en Python para convertir colores entre RGB, HSV, HLS y YIQ, crear paletas y evitar errores de escala

    Ler mais

    Tempo de leitura: 5 minutos
    09/08/2026
    Icono de configuración que representa archivos plist con plistlib en Python
    Bibliotecas y Módulos
    Foto de perfil de Leandro Hirt da Academify

    plistlib en Python: archivos plist

    Aprende plistlib en Python para leer y escribir archivos plist XML y binarios, validar datos y manejar fechas, bytes y

    Ler mais

    Tempo de leitura: 6 minutos
    08/08/2026
    Candado digital que representa credenciales por host con netrc en Python
    Bibliotecas y Módulos
    Foto de perfil de Leandro Hirt da Academify

    netrc en Python: credenciales por host

    Aprende netrc en Python para leer credenciales por host, validar permisos, tratar errores e integrar clientes de red de forma

    Ler mais

    Tempo de leitura: 7 minutos
    08/08/2026
    Mensaje digital que representa codificación quoted-printable con quopri en Python
    Bibliotecas y Módulos
    Foto de perfil de Leandro Hirt da Academify

    quopri en Python: quoted-printable

    Aprende quopri en Python para codificar y decodificar quoted-printable en correo, archivos e integraciones MIME de forma segura.

    Ler mais

    Tempo de leitura: 6 minutos
    08/08/2026