Como usar os métodos __str__() e __repr__() em Python

Introdução

Neste artigo, você aprenderá sobre os métodos especiais __str__() e __repr__() que são definidos no modelo de dados do Python. Os métodos __str__() e __repr__() podem ser úteis na depuração do código Python, fazendo log ou imprimindo informações úteis sobre um objeto.

Os métodos especiais do Python começam e terminam com um duplo sublinhado e são informalmente conhecidos como métodos dunder. Os métodos dunder são os métodos subjacentes para os operadores e funções internas do Python. Você deve evitar chamar os métodos dunder diretamente e, em vez disso, implementar os métodos dunder em sua classe e depois usar as funções internas que os chamam, como str() e repr().

Qual é a diferença entre __str__() e __repr__()?

O método __str__() retorna uma representação em string legível para humanos, ou informal, de um objeto. Este método é chamado pelas funções integradas print(), str() e format(). Se você não definir um método __str__() para uma classe, então a implementação de objeto integrada chama o método __repr__() em seu lugar.

O método __repr__() retorna uma representação em string mais rica em informações, ou oficial, de um objeto. Este método é chamado pela função integrada repr(). Se possível, a string retornada deve ser uma expressão Python válida que possa ser usada para recriar o objeto. Em todos os casos, a string deve ser informativa e não ambígua.

Em geral, a string __str__() é destinada aos usuários e a string __repr__() é destinada aos desenvolvedores.

Exemplos de __str__() e __repr__() usando uma classe integrada

Os exemplos nesta seção chamam os métodos __str__() e __repr__() diretamente para fins de demonstração.

A classe datetime.datetime é uma classe Python integrada que possui uma implementação padrão dos métodos __str__() e __repr__().

O código de exemplo a seguir mostra as strings retornadas pela implementação padrão dos métodos __str__() e __repr__() para um objeto datetime.datetime:

import datetime

mydate = datetime.datetime.now()

print("__str__() string: ", mydate.__str__())
print("str() string: ", str(mydate))

print("__repr__() string: ", mydate.__repr__())
print("repr() string: ", repr(mydate))

O resultado é:

Output
__str__() string: 2023-01-27 09:50:37.429078 str() string: 2023-01-27 09:50:37.429078 __repr__() string: datetime.datetime(2023, 1, 27, 9, 50, 37, 429078) repr() string: datetime.datetime(2023, 1, 27, 9, 50, 37, 429078)

O resultado mostra que a função str() chama __str__() e retorna uma string amigável ao humano, enquanto a função repr() chama __repr__() e retorna uma string mais rica em informações que pode ser usada para recriar o objeto. Na verdade, você pode usar a função repr() com a função eval() para criar um novo objeto a partir da string:

import datetime

mydate1 = datetime.datetime.now()
mydate2 = eval(repr(mydate1))

print("mydate1 repr() string: ", repr(mydate1))
print("mydate2 repr() string: ", repr(mydate2))

print("the values of the objects are equal: ", mydate1==mydate2)

O resultado é:

Output
mydate1 repr() string: datetime.datetime(2023, 1, 26, 9, 43, 24, 479635) mydate2 repr() string: datetime.datetime(2023, 1, 26, 9, 43, 24, 479635) the values of the objects are equal: True

O código de exemplo anterior cria o objeto mydate2 a partir da string repr() para mydate1, e então verifica que os valores de ambos os objetos são iguais.

Exemplos de __str__() e __repr__() Usando uma Nova Classe

Quando você cria uma classe, deve implementar pelo menos o método __repr__() para que informações úteis sejam retornadas quando funções internas usam __repr__().

A seguinte classe não implementa os métodos __str__() ou __repr()__:

class Ocean:

    def __init__(self, sea_creature_name, sea_creature_age):
        self.name = sea_creature_name
        self.age = sea_creature_age

c = Ocean('Jellyfish', 5)

print(str(c))
print(repr(c))

O resultado ao usar str() e repr() é:

Output
<__main__.Ocean object at 0x102892860> <__main__.Ocean object at 0x102892860>

O exemplo anterior demonstra que a implementação padrão de __repr()__ para o objeto retorna uma string com apenas a classe e o id do objeto em formato hexadecimal, o que não é muito útil. Observe que str() e repr() retornam o mesmo valor, pois str() chama __repr__() quando __str__() não está implementado.

Atualize a classe Ocean com implementações dos métodos __str__() e __repr__():

class Ocean:

    def __init__(self, sea_creature_name, sea_creature_age):
        self.name = sea_creature_name
        self.age = sea_creature_age
    
    def __str__(self):
        return f'The creature type is {self.name} and the age is {self.age}'

    def __repr__(self):
        return f'Ocean(\'{self.name}\', {self.age})'

c = Ocean('Jellyfish', 5)

print(str(c))
print(repr(c))

A saída é:

Output
The creature type is Jellyfish and the age is 5 Ocean('Jellyfish', 5)

A implementação de __str__() no exemplo anterior retorna uma string de fácil leitura que fornece os detalhes relevantes do objeto para o usuário. A implementação de __repr__() retorna uma string que é uma expressão Python válida que poderia ser usada para recriar o objeto: Ocean('Jellyfish', 5). O exemplo usa formatação de f-string para as strings, mas você pode formatar as strings usando qualquer formato suportado pelo Python.

Conclusão

Neste artigo, você explorou as diferenças entre os métodos __str__() e __repr__() e implementou esses métodos especiais em uma classe, para que não precisasse chamá-los diretamente. Saiba mais sobre como trabalhar com strings em Python através dos nossos tutoriais de strings em Python.

Source:
https://www.digitalocean.com/community/tutorials/python-str-repr-functions