textwrap no Python: formate textos

Publicado em: 10/08/2026
Tempo de leitura: 5 minutos
Editor de texto representando formatação com textwrap no Python

O módulo textwrap da biblioteca padrão formata parágrafos para terminais, relatórios, logs, mensagens, documentação e interfaces baseadas em texto. Ele quebra linhas respeitando uma largura, adiciona recuos, encurta textos por palavras e remove a indentação comum de strings multilinha. Isso evita funções manuais frágeis e mantém regras de apresentação centralizadas.

Neste guia você aprenderá a usar wrap(), fill(), shorten(), dedent(), indent() e a classe TextWrapper, além de lidar com Unicode, palavras longas, hífens, parágrafos e desempenho.

Quebrar um parágrafo com wrap

wrap() recebe um único parágrafo e devolve uma lista de linhas sem o caractere final de nova linha.

import textwrap

texto = "Python permite criar ferramentas claras para automatizar tarefas repetitivas."
linhas = textwrap.wrap(texto, width=24)
print(linhas)

A largura é medida em caracteres Python, não em pixels nem na largura visual real do terminal. Emojis, caracteres combinantes e ideogramas podem ocupar espaço diferente na tela.

Gerar uma string pronta com fill

fill() equivale a unir o resultado de wrap() com quebras de linha. É a opção mais conveniente para imprimir ou salvar um parágrafo.

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

As duas funções aceitam as mesmas opções, incluindo recuos, controle de palavras longas, hífens, espaços, número máximo de linhas e placeholder.

Recuo inicial e nas linhas seguintes

initial_indent é aplicado à primeira linha. subsequent_indent é aplicado às demais e conta dentro da largura.

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

Esse padrão funciona bem para listas, mensagens de CLI, e-mails em texto simples e relatórios. Defina a largura considerando o prefixo para evitar linhas inesperadamente curtas.

Encurtar por palavras

shorten() primeiro colapsa todos os espaços e depois remove palavras do fim até que o texto e o placeholder caibam na largura.

resumo = textwrap.shorten(
    "Um texto muito longo para aparecer em um cartão pequeno",
    width=32,
    placeholder="...",
)
print(resumo)

A função não corta arbitrariamente no meio do conteúdo normal. Porém, o placeholder precisa caber na largura. Para preservar espaços ou quebras originais, implemente uma política diferente.

Remover a indentação comum com dedent

Strings triplas dentro de funções herdam o recuo do código. dedent() remove a margem comum, mantendo a estrutura relativa.

def mensagem():
    texto = """
        Olá,
          este item permanece recuado.
        Até breve.
    """
    return textwrap.dedent(texto).strip()

Tabs e espaços contam como tipos diferentes de recuo. Misturá-los pode impedir a remoção esperada. No Python 3.14, linhas em branco contendo outros caracteres de espaço também passaram a ser normalizadas corretamente.

Adicionar prefixos com indent

indent() adiciona um prefixo às linhas não vazias por padrão. Um predicado opcional decide quais linhas devem receber o prefixo.

bloco = "primeira\n\nsegunda"
print(textwrap.indent(bloco, "> "))

com_vazias = textwrap.indent(bloco, "+ ", lambda linha: True)

Isso é útil para citações, logs, comentários, blocos de código e mensagens encaminhadas. O predicado recebe a linha incluindo sua quebra, quando presente.

Palavras maiores que a largura

Por padrão, break_long_words=True permite quebrar palavras longas para garantir o limite. Isso pode ser ruim para URLs, hashes, identificadores e comandos.

saida = textwrap.fill(
    "identificador_extremamente_longo_sem_espacos",
    width=20,
    break_long_words=False,
)
print(saida)

Quando a quebra é desativada, uma linha pode ultrapassar a largura. Decida se é mais importante preservar o token ou manter o layout.

Comportamento em hífens

break_on_hyphens=True permite preferir a quebra após hífens. O comportamento é inspirado em convenções do inglês e pode não ser adequado para todos os idiomas ou identificadores técnicos.

Para tokens realmente indivisíveis, defina break_on_hyphens=False e break_long_words=False.

Tabs e outros espaços

expand_tabs=True expande tabs usando tabsize. Depois, replace_whitespace=True substitui tab, newline, tab vertical, form feed e carriage return por espaços simples.

Se replace_whitespace=False, novas linhas internas podem produzir resultados estranhos. Separe o texto em parágrafos antes de formatar.

Um parágrafo por vez

wrap() e fill() são projetados para um único parágrafo. Para textos com vários parágrafos, divida, formate separadamente e preserve as linhas vazias.

def formatar_documento(texto, largura=70):
    blocos = texto.split("\n\n")
    return "\n\n".join(
        textwrap.fill(bloco, width=largura)
        for bloco in blocos
        if bloco.strip()
    )

Documentos reais podem exigir um parser melhor para listas, títulos, tabelas e blocos de código.

Limitar o número de linhas

max_lines e placeholder permitem produzir prévias compactas.

previa = textwrap.fill(
    texto_longo,
    width=50,
    max_lines=2,
    placeholder=" [...]",
)

O placeholder participa do cálculo. Teste larguras pequenas e traduções, pois um texto de continuação maior pode não caber.

Reutilizar TextWrapper

As funções de conveniência criam uma instância a cada chamada. Para formatar muitos textos com a mesma configuração, reutilize TextWrapper.

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

for paragrafo in paragrafos:
    print(wrapper.fill(paragrafo))

A instância é mutável. Evite compartilhá-la entre threads se as opções forem alteradas durante o uso. Uma configuração imutável por worker é mais simples.

Unicode e largura visual

textwrap conta pontos de código conforme o comprimento da string. Terminais podem exibir caracteres asiáticos com largura dupla, acentos combinantes com largura zero e sequências de emoji como um único símbolo visual.

Quando alinhamento visual exato for obrigatório, use uma biblioteca que calcule largura de terminal e ainda aplique textwrap como parte da política textual.

Não usar para HTML ou Markdown sem cuidado

Quebrar texto contendo tags, links Markdown, tabelas ou blocos de código pode separar tokens importantes. Extraia o conteúdo, use um parser ou formate somente partes conhecidas.

Em HTML, espaços e quebras também são interpretados pelo navegador. Não confunda largura textual com layout responsivo de CSS.

Exemplo: ajuda de linha de comando

def ajuda(titulo, descricao):
    cabecalho = textwrap.dedent(f"""
        {titulo}
        {'=' * len(titulo)}
    """).strip()
    corpo = textwrap.fill(
        descricao,
        width=72,
        initial_indent="  ",
        subsequent_indent="  ",
        break_long_words=False,
    )
    return f"{cabecalho}\n{corpo}"

O exemplo separa a estrutura do cabeçalho e o parágrafo, preserva identificadores longos e mantém uma largura consistente.

Erros frequentes

  • Passar vários parágrafos como se fossem um só.
  • Esperar largura visual exata para qualquer Unicode.
  • Quebrar URLs e identificadores sem perceber.
  • Misturar tabs e espaços em strings para dedent().
  • Usar shorten() esperando preservar espaços.
  • Compartilhar uma instância mutável entre threads.
  • Formatar HTML ou Markdown como texto simples.

Boas práticas

  • Defina a finalidade antes de escolher a largura.
  • Formate parágrafos separadamente.
  • Preserve tokens longos quando necessário.
  • Teste traduções e placeholders.
  • Use dedent().strip() em strings triplas.
  • Reutilize TextWrapper em grandes lotes.
  • Separe formatação textual de layout visual.

Conteúdos relacionados

Veja também difflib, locale, pydoc, fileinput e linecache.

Consulte a documentação oficial do textwrap e a documentação de strings.

Conclusão

textwrap oferece uma API completa para apresentação de texto em ambientes com largura limitada. Seu uso correto exige separar parágrafos, definir uma política para tokens longos e entender que quantidade de caracteres não é igual à largura visual em todos os terminais.

Compartilhe:

Facebook
WhatsApp
Twitter
LinkedIn

Conteúdo do artigo

    Artigos relacionados

    Pasta e lupa representando filtros de nomes com fnmatch no Python
    Bibliotecas e Módulos
    Foto de perfil de Leandro Hirt da Academify

    fnmatch no Python: filtre nomes de arquivos

    Aprenda fnmatch no Python para filtrar nomes de arquivos com curingas, controlar maiúsculas, excluir padrões e evitar confundir glob com

    Ler mais

    Tempo de leitura: 5 minutos
    10/08/2026
    Monitor com dados binários representando arrays numéricos compactos no Python
    Bibliotecas e Módulos
    Foto de perfil de Leandro Hirt da Academify

    array no Python: números compactos

    Aprenda array no Python para armazenar números compactos, manipular bytes, arquivos binários e buffers com segurança.

    Ler mais

    Tempo de leitura: 6 minutos
    10/08/2026
    Círculo cromático representando conversões RGB, HSV e HLS com colorsys no Python
    Bibliotecas e Módulos
    Foto de perfil de Leandro Hirt da Academify

    colorsys no Python: RGB, HSV e HLS

    Aprenda colorsys no Python para converter cores entre RGB, HSV, HLS e YIQ, gerar paletas e evitar erros com escalas

    Ler mais

    Tempo de leitura: 6 minutos
    09/08/2026
    Ícone de configuração representando arquivos plist com plistlib no Python
    Bibliotecas e Módulos
    Foto de perfil de Leandro Hirt da Academify

    plistlib no Python: arquivos plist

    Aprenda plistlib no Python para ler e gravar arquivos plist XML e binários, validar dados e integrar configurações Apple com

    Ler mais

    Tempo de leitura: 7 minutos
    08/08/2026
    Cadeado digital representando credenciais por host com netrc no Python
    Bibliotecas e Módulos
    Foto de perfil de Leandro Hirt da Academify

    netrc no Python: credenciais por host

    Aprenda netrc no Python para ler credenciais por host, validar permissões, tratar erros e integrar clientes de rede com segurança.

    Ler mais

    Tempo de leitura: 7 minutos
    08/08/2026
    Mensagem digital representando codificação quoted-printable com quopri no Python
    Bibliotecas e Módulos
    Foto de perfil de Leandro Hirt da Academify

    quopri no Python: quoted-printable

    Aprenda quopri no Python para codificar e decodificar quoted-printable em e-mails, arquivos e integrações MIME com segurança.

    Ler mais

    Tempo de leitura: 7 minutos
    08/08/2026