str vs repr em Python: Explicado
Published 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.
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.
-
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. -
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. -
__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 usandoeval()
.