Dúvida na diferença entre __repr__ e __str__

295 views
Skip to first unread message

João Júnior

unread,
Oct 24, 2011, 7:43:14 AM10/24/11
to python...@yahoogrupos.com.br, python...@googlegroups.com
 

Pessoal,
quando eu uso str() ou print objeto a função __str__ de um objeto é
chamada. Ok, sem problemas. Na documentação diz que se o método
__str__ não está definida em uma classe a função __repr__ é chamada
para retornar a string que representa o objeto, aqui também OK, sem
problemas.
Se eu estiver no interpretador e possuir uma instância de uma classe
que possua __str__ e __repr__ retornando valores diferentes, essa
instância chamada de "a".
Quando eu fizer:
>>>a(e teclar enter)
A __repr__ será chamada, então isso não é o mesmo que imprimir o
objeto, eu pensava que era, o que a máquina virtual faz quando eu
executo a linha acima? Alguém sabe me dizer onde mais o __repr__ é
utilizado(ao invés do __str__?

Valeu!

--
João Júnior
Matemático Computacional - Computational Mathematician

E-mail: joaoju...@gmail.com
Fone: +55 (31) 9642-7061
www.dcc.ufmg.br/~jcaj
http://br.linkedin.com/in/joaojunior

__._,_.___
Atividade nos últimos dias:
.

__,_._,___

Luciano Ramalho

unread,
Oct 24, 2011, 8:01:56 AM10/24/11
to python...@googlegroups.com, python...@yahoogrupos.com.br
2011/10/24 João Júnior <joaoju...@gmail.com>:

> Pessoal,
> quando eu uso str() ou print objeto a função __str__ de um objeto é
> chamada. Ok, sem problemas. Na documentação diz que se o método
> __str__ não está definida em uma classe a função __repr__ é chamada
> para retornar a string que representa o objeto, aqui também OK, sem
> problemas.
> Se eu estiver no interpretador e possuir uma instância de uma classe
> que possua __str__ e __repr__ retornando valores diferentes, essa
> instância chamada de "a".
> Quando eu fizer:
>>>>a(e teclar enter)
> A __repr__ será chamada, então isso não é o mesmo que imprimir o
> objeto, eu pensava que era, o que a máquina virtual faz quando eu
> executo a linha acima? Alguém sabe me dizer onde mais o __repr__ é
> utilizado(ao invés do __str__?

João,

Qq linguagem OO que se preze tem um método padrão para transformar um
objeto em string. Por exemplo, em Java, o método se chama .toString.

Mas o Guido, que criou o Python, é um gênio, e ele percebeu que na
verdade é melhor ter 2 métodos para transformar um objeto em uma
string:

o .__str__, que serve para exibir o objeto para usuário final, usada
pelo comando print e pela função str
o .__repr__, que serve para exibir o objeto para o programador, usada
pelo console do Python e pela funçao repr

Quando queremos exibir para o usuário final, queremos deixar de fora
detalhes que podem confundí-lo. Por exemplo, em Python 2.6 temos:

>>> f = 11.0/10
>>> f
1.1000000000000001
>>> print f
1.1
>>> str(f)
'1.1'
>>> repr(f)
'1.1000000000000001'
>>>

Note que 11.0/10 em Python dá 1.1000000000000001. Este pequeno erro
acontece porque existem imprecisões inevitáveis na conversão de
decimal para a representação binária de números de ponto flutuante na
biblioteca padrão da linguagem C, que o Python usa. Esta é a
representação interna do número, e é o que o método __repr__ devolve.
Para exibir para o usuário, usamos print, que usa __str__ e exibe uma
aproximação para não deixar o usuário final nervoso com um erro que na
verdade é bem pequeno mas visualmente parece grande.

Outro exemplo:

>>> s = u'avião'
>>> s
u'avi\xe3o'
>>> print s
avião
>>> print repr(s)
u'avi\xe3o'
>>>

Note que, ao exibir uma string Unicode, o repr coloca o prefixo u na
frente, e troca qq caractere não-ASCII por uma representação
hexadecimal. Mas o str mostra o resultado de um jeito mais amigável,
se o terminal suportar a codificação... Portanto o repr tem a
desvantagem de mostrar uma string pouco legível, porém sempre fiel ao
conteúdo, independente da codificação do terminal. Já o str tenta
mostrar uma versão amigável da string, mas isso pode não ser possível
em qualquer saída, devido a problemas de encoding.

A idéia, por fim, é que o repr tenta ser sempre a representação mais
fiel do valor, de modo que isso seja sempre que possível verdadeiro:

>>> f
1.1000000000000001
>>> g = eval(repr(f))
>>> g == f
True


--
Luciano Ramalho
Twitter: @luciano
Autor e instrutor da Academia Python na Globalcode
http://python.globalcode.com.br

Luciano Ramalho

unread,
Oct 24, 2011, 8:06:17 AM10/24/11
to python...@googlegroups.com, python...@yahoogrupos.com.br
2011/10/24 Luciano Ramalho <luc...@ramalho.org>:

> Mas o Guido, que criou o Python, é um gênio, e ele percebeu que na
> verdade é melhor ter 2 métodos para transformar um objeto em uma
> string:
>
> o .__str__,  que serve para exibir o objeto para usuário final, usada
> pelo comando print e pela função str
> o .__repr__, que serve para exibir o objeto para o programador, usada
> pelo console do Python e pela funçao repr

Apenas completando: no Python 2.x, temos um terceiro método:

o .__unicode__, que funciona como o __str__ mas gera uma representação
objeto na forma de uma instância de unicode (em vez de uma string de
bytes, que é o que os outros dois fazem). Quem usa Django logo aprende
que o jeito certo de exibir dados para o usuário final no Django é
sempre via __unicode__, pq daí ele faz as conversões necessárias.

Em Python 3 tudo isso foi simplificado, porque a classe str no Python
3 suporta Unicode, então a classe unicode tornou-se obsoleta, e junto
com ela o método __unicode__ também se foi.

João Júnior

unread,
Oct 24, 2011, 8:55:34 AM10/24/11
to python...@googlegroups.com
ok!
Valeu Luciano.

> --
> ------------------------------------
> Grupo Python-Brasil
> http://www.python.org.br/wiki/AntesDePerguntar
>
> <*> Para visitar o site do grupo na web, acesse:
>    http://groups.google.com/group/python-brasil
>
> <*> Para sair deste grupo, envie um e-mail para:
>    python-brasi...@googlegroups.com

Rodrigo Ferreira de Souza

unread,
Oct 24, 2011, 9:38:25 AM10/24/11
to python...@yahoogrupos.com.br
Bom dia João,

Voce pode usar o repr(objeto) e o str(objeto) caso queira usar os 2 métodos
e utilizar cada um em um ponto do programa..

Mas fique atento.. também existe o __unicode__ que é chamado no método
unicode(objeto).

É recomendado utilizar quando possível unicode nas strings para não ter
problemas com acentuação.

Atenciosamente,
Rodrigo

2011/10/24 João Júnior <joaoju...@gmail.com>

> **


>
>
> Pessoal,
> quando eu uso str() ou print objeto a função __str__ de um objeto é
> chamada. Ok, sem problemas. Na documentação diz que se o método
> __str__ não está definida em uma classe a função __repr__ é chamada
> para retornar a string que representa o objeto, aqui também OK, sem
> problemas.
> Se eu estiver no interpretador e possuir uma instância de uma classe
> que possua __str__ e __repr__ retornando valores diferentes, essa
> instância chamada de "a".
> Quando eu fizer:
> >>>a(e teclar enter)
> A __repr__ será chamada, então isso não é o mesmo que imprimir o
> objeto, eu pensava que era, o que a máquina virtual faz quando eu
> executo a linha acima? Alguém sabe me dizer onde mais o __repr__ é
> utilizado(ao invés do __str__?
>
> Valeu!
>
> --
> João Júnior
> Matemático Computacional - Computational Mathematician
>
> E-mail: joaoju...@gmail.com
> Fone: +55 (31) 9642-7061
> www.dcc.ufmg.br/~jcaj
> http://br.linkedin.com/in/joaojunior
>
>


[As partes desta mensagem que não continham texto foram removidas]

------------------------------------

Python-Brasil
http://www.python.org.br/wiki/AntesDePerguntar
Links do Yahoo! Grupos

<*> Para visitar o site do seu grupo na web, acesse:
http://br.groups.yahoo.com/group/python-brasil/

<*> Para sair deste grupo, envie um e-mail para:

python-brasi...@yahoogrupos.com.br

<*> O uso que você faz do Yahoo! Grupos está sujeito aos:
http://br.yahoo.com/info/utos.html


Hugo Lopes Tavares

unread,
Oct 24, 2011, 5:13:49 PM10/24/11
to python...@yahoogrupos.com.br, python...@googlegroups.com
 

2011/10/24 João Júnior <joaoju...@gmail.com>
...


> A __repr__ será chamada, então isso não é o mesmo que imprimir o
> objeto, eu pensava que era, o que a máquina virtual faz quando eu
> executo a linha acima? Alguém sabe me dizer onde mais o __repr__ é
> utilizado(ao invés do __str__?

O método __str__ é usado pelo `print`, por exemplo. Mas como o Rodrigo
já disse, muitas vezes o __unicode__ é utilizado também. Vale olhar a
documentação da biblioteca/ferramenta que você estiver utilizando.

__._,_.___
.

__,_._,___
Reply all
Reply to author
Forward
0 new messages