O módulo reprlib ajuda a produzir representações abreviadas de objetos. Em vez de imprimir uma lista com milhões de elementos, uma string enorme ou uma estrutura profundamente aninhada, ele limita comprimento, quantidade de itens e profundidade. Isso é útil em logs, consoles, debuggers, mensagens de erro, ferramentas de inspeção e interfaces administrativas.
Uma representação curta não deve ser confundida com serialização. O resultado serve para pessoas e diagnóstico, não para reconstruir o objeto. Ele também pode conter dados sensíveis se o objeto os expõe em repr(). Limites de tamanho reduzem volume, mas não substituem redaction, controle de acesso ou uma política de logging.
repr e reprlib
A função embutida repr() tenta produzir uma representação inequívoca e útil ao desenvolvedor.
dados = list(range(1000))
print(repr(dados))
Em objetos grandes, o texto pode ocupar memória, poluir logs e dificultar a leitura. reprlib.repr() usa uma instância padrão de Repr para abreviar.
import reprlib
print(reprlib.repr(dados))
Tipos suportados
A implementação conhece tipos comuns como strings, bytes, listas, tuplas, sets, frozensets, dicionários, arrays e objetos genéricos. Para containers, ela limita a quantidade de elementos; para texto, limita caracteres.
Objetos personalizados ainda dependem do próprio __repr__(), a menos que você crie uma especialização.
Crie uma instância Repr
A classe Repr possui atributos de configuração que controlam os limites.
from reprlib import Repr
resumo = Repr()
resumo.maxlist = 5
resumo.maxstring = 40
resumo.maxdict = 4
print(resumo.repr(dados))
Use uma instância por política de apresentação. Um console pode aceitar mais detalhes que um log de produção.
Limite de listas
maxlist define quantos elementos de uma lista aparecem. O módulo seleciona uma quantidade limitada e insere reticências para indicar omissão.
A representação não informa necessariamente quantos itens foram removidos. Quando essa informação importa, registre separadamente len(lista).
Tuplas
maxtuple controla tuplas. Tuplas com um elemento mantêm a vírgula necessária para representar sua forma.
resumo.maxtuple = 3
print(resumo.repr(tuple(range(20))))
Não analise o texto de volta com eval(). A saída abreviada contém reticências e pode não ser uma expressão válida ou completa.
Sets e frozensets
maxset e maxfrozenset limitam conjuntos. Como sets não possuem ordem semântica estável, a seleção visual de elementos pode variar.
Não use a representação para snapshots determinísticos entre ambientes. Para testes, ordene uma coleção derivada quando os elementos forem comparáveis.
Dicionários
maxdict limita pares chave-valor.
resumo.maxdict = 3
config = {f"chave_{i}": i for i in range(20)}
print(resumo.repr(config))
Uma chave sensível pode aparecer mesmo em uma amostra pequena. Redija ou filtre o mapping antes de chamar repr.
Strings
maxstring controla o comprimento de strings.
resumo.maxstring = 30
print(resumo.repr("a" * 500))
A abreviação tenta preservar partes do início e do fim. Isso é útil para IDs longos, caminhos e mensagens, mas pode expor prefixos e sufixos secretos.
Long strings em objetos
maxlong está relacionado a representações longas em determinados caminhos de formatação. A política exata depende do tipo e da versão do Python.
Teste com os objetos reais da aplicação. Não presuma que um único atributo limita todo texto produzido por objetos personalizados.
Bytes e bytearray
maxstring também influencia representações de sequências de bytes em vários casos. Bytes podem conter dados binários, tokens ou conteúdo pessoal.
Para payloads, prefira registrar tamanho, hash e uma amostra explicitamente sanitizada.
Outros containers
Atributos como maxarray, maxdeque e maxother controlam outras categorias. Consulte a versão do Python usada no projeto para a lista completa.
Configurar um valor muito alto remove a proteção prática contra explosão de logs.
maxlevel e profundidade
maxlevel limita a profundidade de estruturas aninhadas.
resumo.maxlevel = 2
aninhado = {"a": {"b": {"c": {"d": 1}}}}
print(resumo.repr(aninhado))
Isso evita atravessar uma árvore enorme apenas para produzir diagnóstico.
Objetos recursivos
Containers podem referenciar a si mesmos.
lista = []
lista.append(lista)
print(repr(lista))
O sistema de representação do Python detecta vários ciclos e usa marcadores. reprlib adiciona limites, mas uma implementação personalizada de __repr__() ainda pode entrar em recursão se não tiver proteção.
recursive_repr
O decorator recursive_repr() ajuda a proteger métodos __repr__() contra chamadas recursivas.
from reprlib import recursive_repr
class No:
def __init__(self, valor):
self.valor = valor
self.proximo = None
@recursive_repr(fillvalue="...")
def __repr__(self):
return f"No({self.valor!r}, proximo={self.proximo!r})"
Quando o mesmo objeto é encontrado novamente na mesma thread de representação, o decorator devolve o marcador.
Escolha do fillvalue
O argumento fillvalue define o texto usado para indicar recursão. Mantenha um valor curto e reconhecível.
Não use um texto que possa ser confundido com dado real da aplicação. O objetivo é deixar claro que a saída foi interrompida.
Subclasse Repr
Você pode criar uma subclasse para personalizar tipos.
from reprlib import Repr
class ReprAplicacao(Repr):
def repr_Usuario(self, obj, level):
return f"Usuario(id={obj.id!r})"
O nome do método segue o tipo. Confirme o mecanismo com testes, porque herança, nomes qualificados e classes dinâmicas podem exigir uma abordagem diferente.
Redaction antes da representação
Para objetos com senhas, tokens, chaves e dados pessoais, crie uma versão sanitizada.
def sanitizar(config):
ocultas = {"password", "token", "secret"}
return {
chave: "***" if chave.lower() in ocultas else valor
for chave, valor in config.items()
}
Depois aplique reprlib à estrutura sanitizada. Limitar comprimento não garante segredo.
Logs estruturados
Em logging JSON, é melhor registrar campos separados como tipo, tamanho, contagem e amostra do que colocar toda a representação em uma string.
reprlib pode gerar a amostra, mas mantenha metadados pesquisáveis e limites no pipeline de observabilidade.
Mensagens de erro
Uma exceção pode incluir um resumo do valor inválido.
valor_curto = resumo.repr(valor)
raise ValueError(f"valor inválido: {valor_curto}")
Evite incluir entrada não confiável sem escapar quando a mensagem será exibida em HTML, terminal com cores ou outro contexto interpretável.
Terminais e sequências de controle
Strings podem conter caracteres de controle. repr() normalmente escapa muitos deles, mas logs e UIs ainda precisam de tratamento adequado.
Não imprima bytes arbitrários diretamente no terminal. Use uma representação textual limitada.
Desempenho
Limitar a saída reduz o texto final, mas a criação da representação pode ainda chamar __repr__() de objetos selecionados. Um método personalizado pode ser lento, acessar rede ou produzir side effects, o que é uma má prática.
__repr__() deve ser rápido, seguro e sem efeitos observáveis.
Objetos lazy
Não materialize generators ou iterators apenas para representá-los. Isso pode consumir o stream e alterar a aplicação.
Registre o tipo, estado conhecido e identificador. Um repr seguro não deve forçar computação cara.
Data classes
Dataclasses geram __repr__() automaticamente. Campos podem ser excluídos com repr=False.
from dataclasses import dataclass, field
@dataclass
class Credencial:
usuario: str
senha: str = field(repr=False)
Combine essa proteção com redaction, porque objetos aninhados ainda podem revelar informações.
Representação e estabilidade
O formato de repr de tipos internos pode mudar entre versões do Python. Não use representações humanas como protocolo, chave de cache, assinatura ou formato persistente.
Para persistência, use JSON, banco de dados ou outro formato versionado.
Snapshots de teste
Snapshots baseados em repr podem ser frágeis por ordem de sets, endereços de memória e mudanças de versão. Normalize dados e remova valores instáveis.
Teste também os limites: estrutura pequena, exatamente no limite e acima dele.
repr personalizado
Um bom __repr__() inclui tipo e campos que ajudam a identificar o estado, mas omite segredos e coleções enormes.
def __repr__(self):
return f"Job(id={self.id!r}, status={self.status!r})"
Use reprlib dentro do método quando um campo variável pode ser grande.
Erros comuns
Os erros mais frequentes são tratar repr como serialização, acreditar que abreviação protege segredos, definir limites altos demais, materializar iterators, criar __repr__() lento, depender de ordem de sets, fazer parse da saída e usar snapshots instáveis entre versões.
Conclusão
reprlib ajuda a manter representações legíveis e limitadas em logs, consoles e diagnósticos. Configure uma instância Repr por contexto, limite profundidade e containers, use recursive_repr em estruturas cíclicas e sanitize dados antes da formatação.
Consulte a documentação oficial de reprlib e o artigo sobre ast no Python para outras ferramentas de inspeção estrutural.







