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
TextWrapperem 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.







