Skip to content

str vs repr em Python: Explicado

Updated on

No mundo da programação Python, __str__ e __repr__ são métodos "dunder" (dois underscores), também conhecidos como métodos mágicos ou métodos especiais. Eles são a base para a programação orientada a objetos em Python. Este guia abrangente pretende iluminar as funcionalidades distintas desses dois métodos, sua importância no Python e as instâncias adequadas para sua aplicação. Além disso, este guia apresentará vários exemplos de código para solidificar os conceitos subjacentes.

Deseja criar rapidamente visualizações de dados a partir de um DataFrame Pandas de Python sem código?

PyGWalker é uma biblioteca Python para Análise Exploratória de Dados com Visualização. PyGWalker (opens in a new tab) pode simplificar sua análise de dados e seu fluxo de trabalho de visualização de dados no Jupyter Notebook, transformando seu DataFrame pandas (e polars dataframe) em uma interface de usuário no estilo Tableau para exploração visual.

PyGWalker para visualização de dados (opens in a new tab)

Definindo os Termos: __str__ vs __repr__

Antes de aprofundarmos, vamos começar definindo esses dois métodos importantes:

Método __str__

No Python, __str__ é o método usado para computar a representação de string "informal" ou facilmente imprimível de um objeto. Ele tem como objetivo fornecer uma saída legível para humanos. Assim, a legibilidade é uma consideração importante ao implementar esse método.

Aqui está um exemplo simples:

class Pessoa:
    def __init__(self, nome, idade):
        self.nome = nome
        self.idade = idade
 
    def __str__(self):
        return f'{self.nome} tem {self.idade} anos.'
 
joao = Pessoa('João Silva', 30)
print(str(joao))  # Produz: João Silva tem 30 anos.

Método __repr__

Por outro lado, __repr__ é um método usado para computar a representação de string "oficial" de um objeto. Seu propósito é fornecer uma representação detalhada que poderia ser usada para recriar o objeto se fosse alimentada para a função eval(). É especialmente útil para depuração e registro, pois fornece uma descrição abrangente do objeto.

Considere a mesma classe Pessoa, mas com um método __repr__:

class Pessoa:
    def __init__(self, nome, idade):
        self.nome = nome
        self.idade = idade
 
    def __repr__(self):
        return f'Pessoa(nome={self.nome}, idade={self.idade})'
 
joao = Pessoa('João Silva', 30)
print(repr(joao))  # Produz: Pessoa(nome=João Silva, idade=30)

A saída do método __repr__ é muito mais detalhada e técnica em comparação com o método __str__. Esse nível de detalhe é exatamente o que um desenvolvedor precisa para depuração ou registro eficazes.

Quando Usar __str__ vs __repr__

Agora que temos uma compreensão básica desses métodos, vamos explorar quando usar cada um.

Implementando __str__ para uma Representação de String Facilmente Legível

O método __str__ é principalmente direcionado aos usuários finais. Ele fornece uma descrição informal mais legível de um objeto. Você pode pensar nele como uma forma de exibir objetos de maneira que faça sentido para usuários que não são necessariamente programadores.

Ao implementar esse método em suas classes Python, concentre-se em fornecer informações relevantes e benéficas para o usuário final.

class Produto:
    def __init__(self, nome, preco):
        self.nome = nome
        self.preco = preco
 
    def __str__(self):
        return f'{self.nome} custa R${self.preco}.'
 
iphone = Produto('iPhone', 999)
print(str(iphone))  # Produz: iPhone custa R$999.

No exemplo acima, o método __str__ fornece uma descrição simples e legível para humanos do objeto Produto. A saída de str(iphone) pode ser exibida diretamente para usuários em um site ou em um aplicativo.

Implementando __repr__ para Depuração e Desenvolvimento

O método __repr__, por outro lado, é principalmente destinado a desenvolvedores. Ele fornece uma representação completa e não ambígua do objeto, que pode ser muito útil para depuração e registro.

Uma regra de ouro ao implementar o método __repr__ é que ele deve, se possível, retornar uma string que permita a recriação do objeto usando a função eval(). Isso nem sempre é possível, especialmente para objetos complexos, mas é uma boa diretriz a ser seguida.

Considere a classe Produto com um método __repr__:

class Produto:
    def __init__(self, nome, preco):
        self.nome = nome
        self.preco = preco
 
    def __repr__(self):
        return f'Produto(nome={self.nome}, preco={self.preco})'
 
iphone = Produto('iPhone', 999)
print(repr(iphone))  # Produz: Produto(nome=iPhone, preco=999)

A saída do método __repr__ é muito mais detalhada e técnica em comparação com o método __str__. Esse nível de detalhe é exatamente o que um desenvolvedor precisa para depuração ou registro eficazes.

Personalizando __str__ e __repr__ para suas Classes Python

Agora que você entende os casos de uso principais de ambos os métodos, vamos discutir como personalizá-los para atender às suas necessidades. Em muitos casos, você desejará definir ambos os métodos em suas classes, mas sua implementação dependerá muito do caso de uso específico.

Estabelecendo __str__ para uma Representação de String Informal Personalizada

Ao definir o método __str__, pense nas pessoas que interagirão com seu objeto e no que elas precisam saber. O método deve retornar uma string que forneça um resumo conciso e legível para humanos do objeto.

Suponhamos que temos uma classe Filme em um aplicativo de reserva de ingressos para o cinema:

class Filme:
    def __init__(self, titulo, diretor, avaliacao):
        self.titulo = titulo
        self.diretor = diretor
        self.avaliacao = avaliacao
 
def __str__(self):
    return f'{self.title} por {self.director}, classificado {self.rating}/10.'
 
inception = Filme('Inception', 'Christopher Nolan', 8.8)
print(str(inception))  # Saída: Inception por Christopher Nolan, classificou 8.8/10.

Construindo __repr__ para Descrição Detalhada do Objeto

Ao implementar o método __repr__, considere o que seria útil para alguém depurando o código ou registrando o estado de um objeto. A string deve incluir todas as informações necessárias para entender o objeto de relance.

Continuando com a classe Filme, um método __repr__ poderia ser assim:

class Filme:
    def __init__(self, título, diretor, classificação):
        self.título = título
        self.diretor = diretor
        self.classificação = classificação
 
    def __repr__(self):
        return f'Filme(título={self.título}, diretor={self.diretor}, classificação={self.classificação})'
 
inception = Filme('Inception', 'Christopher Nolan', 8.8)
print(repr(inception))  # Saída: Filme(título=Inception, diretor=Christopher Nolan, classificação=8.8)

Perguntas frequentes: Entendendo __str__ e __repr__ no Python

Agora exploramos os conceitos principais dos métodos __str__ e __repr__ do Python. No entanto, você ainda pode ter dúvidas sobre esses métodos especiais. Vamos responder algumas perguntas frequentes.

  1. O que acontece se eu não definir __str__ e __repr__ na minha classe Python?

    Se você não definir __str__ ou __repr__ na sua classe, o Python usará suas implementações padrão. O método __str__ padrão retorna uma string contendo o nome da classe e seu endereço na memória, enquanto o __repr__ padrão faz o mesmo.

  2. Devo sempre implementar os métodos __str__ e __repr__ em todas as minhas classes?

    É uma boa prática implementar pelo menos __repr__, pois ele é usado como alternativa se __str__ não for definido. No entanto, implementar ambos depende das suas necessidades específicas. Se os objetos da sua classe precisam ter uma representação de string amigável ao usuário, então vale a pena implementar __str__ também.

  3. __str__ e __repr__ podem retornar qualquer tipo de string?

    Embora __str__ e __repr__ possam tecnicamente retornar qualquer string, é melhor seguir as convenções: __str__ deve ser legível e conciso, enquanto __repr__ deve ser detalhado e, se possível, permitir que o objeto seja reproduzido usando eval().