Diferença entre __str__ e __repr__?

Respostas:

2724

Alex resumiu bem, mas, surpreendentemente, foi muito sucinto.

Primeiro, deixe-me reiterar os pontos principais no post de Alex :

  • A implementação padrão é inútil (é difícil pensar em uma que não seria, mas sim)
  • __repr__ objetivo é ser inequívoco
  • __str__ objetivo é ser legível
  • O contêiner __str__usa objetos contidos '__repr__

A implementação padrão é inútil

Isso é principalmente uma surpresa, porque os padrões do Python tendem a ser bastante úteis. No entanto, nesse caso, ter um padrão para o __repr__qual agiria como:

return "%s(%r)" % (self.__class__, self.__dict__)

teria sido muito perigoso (por exemplo, muito fácil entrar em recursão infinita se objetos se referirem uns aos outros). Então, o Python aguenta. Observe que há um padrão que é verdadeiro: se __repr__for definido e __str__não, o objeto se comportará como se __str__=__repr__.

Isso significa, em termos simples: quase todos os objetos que você implementa devem ter um funcional __repr__que seja útil para entender o objeto. Implementando__str__ é opcional: faça isso se você precisar de uma funcionalidade de "impressão bonita" (por exemplo, usada por um gerador de relatórios).

O objetivo __repr__é ser inequívoco

Deixe-me falar e dizer: não acredito em depuradores. Realmente não sei como usar nenhum depurador e nunca o usei seriamente. Além disso, acredito que a grande falha nos depuradores é sua natureza básica - a maioria das falhas depuradoras aconteceu há muito tempo, em uma galáxia muito distante. Isso significa que eu acredito, com fervor religioso, na exploração madeireira. O registro é a força vital de qualquer sistema de servidor decente de ignorar. O Python facilita o log: com talvez alguns wrappers específicos do projeto, tudo o que você precisa é de um

log(INFO, "I am in the weird function and a is", a, "and b is", b, "but I got a null C — using default", default_c)

Mas você precisa executar o último passo - verifique se todos os objetos implementados têm uma repr útil, para que um código como esse possa funcionar. É por isso que a coisa “eval” surge: se você tem informações suficientes eval(repr(c))==c, significa que você sabe tudo o que há para saber c. Se isso é fácil o suficiente, pelo menos de uma maneira difusa, faça-o. Caso contrário, verifique se você tem informações suficientes c. Eu costumo usar um eval-like formato: "MyClass(this=%r,that=%r)" % (self.this,self.that). Isso não significa que você pode realmente criar MyClass, ou que esses são os argumentos corretos do construtor - mas é uma forma útil de expressar “isso é tudo o que você precisa saber sobre essa instância”.

Nota: Eu usei %racima, não %s. Você sempre deseja usar repr()[ou %rformatar caracteres, de forma equivalente] dentro da __repr__implementação, ou está derrotando o objetivo de repr. Você quer ser capaz de diferenciar MyClass(3)e MyClass("3").

O objetivo __str__é ser legível

Especificamente, não se destina a ser inequívoco - observe isso str(3)==str("3"). Da mesma forma, se você implementar uma abstração de IP, ter o str dela parecido com 192.168.1.1 é bom. Ao implementar uma abstração de data / hora, o str pode ser "2010/4/12 15:35:22" etc. O objetivo é representá-lo de uma maneira que um usuário, não um programador, deseje lê-lo. Pique dígitos inúteis, finja ser de outra classe - desde que apóie a legibilidade, é uma melhoria.

O contêiner __str__usa objetos contidos '__repr__

Isso parece surpreendente, não é? É um pouco, mas quão legível seria se usasse o deles __str__?

[moshe is, 3, hello
world, this is a list, oh I don't know, containing just 4 elements]

Não muito. Especificamente, as seqüências de caracteres em um contêiner acham muito fácil perturbar sua representação. Diante da ambiguidade, lembre-se, Python resiste à tentação de adivinhar. Se você deseja o comportamento acima ao imprimir uma lista, basta

print "[" + ", ".join(l) + "]"

(você provavelmente também pode descobrir o que fazer com os dicionários.

Sumário

Implemente __repr__para qualquer classe que você implemente. Isso deve ser uma segunda natureza. Implemente __str__se você acha que seria útil ter uma versão de string que erre no lado da legibilidade.

moshez
fonte
154
Definitivamente discordo de sua opinião de que a depuração não é o caminho a percorrer. Para desenvolvimento, use um depurador (e / ou log); para produção, use log. Com um depurador, você tem uma visão de tudo que deu errado quando o problema ocorreu. Você pode ver a imagem completa. A menos que você esteja registrando TUDO, você não pode obter isso. Além disso, se você estiver registrando tudo, precisará percorrer toneladas de dados para obter o que deseja.
Samuel
21
Ótima resposta (exceto a parte sobre não usar depuradores). Gostaria apenas de adicionar um link a outras perguntas e respostas sobre str vs unicode no Python 3, que podem ser relevantes para a discussão de pessoas que fizeram a troca.
ThatAintWorking 23/03
11
O plus1 para depuradores é inútil e não escala nem um centavo. Obtenha seu rendimento de registro em vez disso. E sim, este foi um post bem escrito. Acontece que __repr__era o que eu precisava para depurar. Obrigado pela ajuda.
personal_cloud
7
o depurador loucura de lado, eu aprendi a% r e que vale a pena o voto de qualquer maneira
Mickey Perlstein
7
no depurador vs sem depurador: não receba opiniões tão arraigadas. Em alguns aplicativos, a depuração não é realista, geralmente quando há envolvimento em tempo real ou quando o código é executado remotamente apenas em uma plataforma com pouco acesso ou sem console. Na maioria dos outros casos, será muito mais rápido parar em uma exceção para investigar ou definir um ponto de interrupção, porque você não precisa passar por milhares de linhas de log (o que atrapalhará seu disco e diminuirá a velocidade do aplicativo). Por fim, nem sempre é possível fazer logon, por exemplo, em dispositivos incorporados, o depurador também é seu amigo.
RedGlyph
523

Minha regra de ouro: __repr__é para desenvolvedores, __str__é para clientes.

Ned Batchelder
fonte
2
Isso é verdade porque para obj = uuid.uuid1 (), obj .__ str __ () é "2d7fc7f0-7706-11e9-94ae-0242ac110002" e obj .__ repr __ () é "UUID ('2d7fc7f0-7706-11e9-94ae-0242ac11000 ') ". Os desenvolvedores precisam (valor + origem), enquanto os clientes precisam de um valor e eles não se importam com o que conseguiram!
Naren Yellavula 15/05/19
1
Aqui, cliente pode não significar necessariamente usuário final. É o cliente ou usuário do objeto. Portanto, se for um SDK, os desenvolvedores do SDK usarão __str__para que os desenvolvedores normais tenham um objeto legível. Por outro lado, __repr__é para os próprios desenvolvedores do SDK.
Shiplu Mokaddim 9/01
398

A menos que você aja especificamente para garantir o contrário, a maioria das classes não terá resultados úteis para:

>>> class Sic(object): pass
... 
>>> print str(Sic())
<__main__.Sic object at 0x8b7d0>
>>> print repr(Sic())
<__main__.Sic object at 0x8b7d0>
>>> 

Como você vê - nenhuma diferença e nenhuma informação além da classe e do objeto id. Se você substituir apenas um dos dois ...:

>>> class Sic(object): 
...   def __repr__(object): return 'foo'
... 
>>> print str(Sic())
foo
>>> print repr(Sic())
foo
>>> class Sic(object):
...   def __str__(object): return 'foo'
... 
>>> print str(Sic())
foo
>>> print repr(Sic())
<__main__.Sic object at 0x2617f0>
>>> 

como você vê, se você substituir __repr__, isso também é usado __str__, mas não vice-versa.

Outros boatos cruciais a saber: __str__em um contêiner embutido, usa __repr__NÃO __str__, para os itens que ele contém. E, apesar das palavras sobre o assunto encontradas nos documentos típicos, quase ninguém se incomoda em tornar os __repr__objetos uma string que evalpode ser usada para criar um objeto igual (é muito difícil e NÃO saber como o módulo relevante foi realmente importado o torna realmente impossível).

Então, meu conselho: concentre-se em tornar __str__razoavelmente legível para o ser humano e o __repr__mais inequívoco possível, mesmo que isso interfira no objetivo impreciso e impreciso de tornar __repr__o valor retornado aceitável como entrada __eval__!

Alex Martelli
fonte
34
Nos meus testes de unidade, sempre verifico eval(repr(foo))se o objeto é igual a foo. Você está certo de que não funcionará fora dos meus casos de teste, pois não sei como o módulo é importado, mas isso pelo menos garante que funcione em algum contexto previsível. Eu acho que é uma boa maneira de avaliar se o resultado de__repr__ é suficientemente explícito. Fazer isso em um teste de unidade também ajuda a garantir que as __repr__alterações sejam seguidas na classe.
Steven T. Snyder
4
Eu sempre tento ter certeza de que eval(repr(spam)) == spam(pelo menos no contexto certo) ou eval(repr(spam))gera um SyntaxError. Dessa forma, você evita confusão. (E isso é quase verdade para os builtins e a maioria dos stdlib, exceto, por exemplo, listas recursivas, onde a=[]; a.append(a); print(eval(repr(a)))você fornece [[Ellipses]]...) É claro que eu não faço isso para realmente usá-lo eval(repr(spam)) , exceto como verificação de sanidade nos testes de unidade ... mas eu que , por vezes, copiar e colar repr(spam)em uma sessão interativa.
abarnert
Por que os contêineres (listas, tuplas) não usariam __str__para cada elemento em vez de __repr__? Parece totalmente errado para mim, pois implementei um legível __str__no meu objeto e, quando faz parte de uma lista, vejo o mais feio __repr__.
SuperGeo 26/01
Acabei de encontrar um bug irritante relacionado ao fato de que eval(repr(x))falha mesmo para os tipos internos: class A(str, Enum): X = 'x'aumentará o SyntaxError eval(repr(A.X)). É triste, mas compreensível. BTW, eval(str(A.X))na verdade funciona, mas é claro apenas se class Aestiver no escopo - portanto, provavelmente não é muito útil.
max
@SuperGeo Outras respostas abrangem isso: strelemento de uso de contêiner reprporque [1, 2, 3]! = ["1", "2, 3"].
Mtraceur #:
163

__repr__: a representação do objeto python geralmente eval o converterá novamente nesse objeto

__str__: é o que você acha que é esse objeto em forma de texto

por exemplo

>>> s="""w'o"w"""
>>> repr(s)
'\'w\\\'o"w\''
>>> str(s)
'w\'o"w'
>>> eval(str(s))==s
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 1
    w'o"w
       ^
SyntaxError: EOL while scanning single-quoted string
>>> eval(repr(s))==s
True
Andrew Clark
fonte
151

Em resumo, o objetivo de __repr__é ser inequívoco e __str__legível.

Aqui está um bom exemplo:

>>> import datetime
>>> today = datetime.datetime.now()
>>> str(today)
'2012-03-14 09:21:58.130922'
>>> repr(today)
'datetime.datetime(2012, 3, 14, 9, 21, 58, 130922)'

Leia esta documentação para repr:

repr(object)

Retorne uma string contendo uma representação imprimível de um objeto. Esse é o mesmo valor gerado pelas conversões (aspas reversas). Às vezes, é útil poder acessar esta operação como uma função comum. Para muitos tipos, essa função tenta retornar uma sequência que daria origem a um objeto com o mesmo valor quando transmitida eval(); caso contrário, a representação é uma sequência entre colchetes angulares que contém o nome do tipo do objeto juntamente com informações adicionais geralmente incluindo o nome e o endereço do objeto. Uma classe pode controlar o que essa função retorna para suas instâncias, definindo um __repr__()método.

Aqui está a documentação para str:

str(object='')

Retorna uma string contendo uma representação bem imprimível de um objeto. Para cadeias, isso retorna a própria cadeia. A diferença repr(object)é que str(object)nem sempre tente retornar uma string aceitável eval(); seu objetivo é retornar uma sequência imprimível. Se nenhum argumento for fornecido, retornará a string vazia '',.

bitoffdev
fonte
1
Qual é o significado da string imprimível aqui? Você pode explicar isso por favor?
Vicrobot
115

Qual é a diferença entre __str__e __repr__no Python?

__str__(lidos como "dunder (sublinhado duplo)") e __repr__(lidos como "dunder-repper" (para "representação")) são métodos especiais que retornam seqüências de caracteres com base no estado do objeto.

__repr__fornece comportamento de backup se __str__estiver ausente.

Portanto, deve-se primeiro escrever um __repr__que permita restabelecer um objeto equivalente a partir da string que ele retorna, por exemplo, usando evalou digitando caractere por caractere em um shell Python.

A qualquer momento, pode-se escrever um __str__para uma representação de string legível pelo usuário da instância, quando julgar necessário.

__str__

Se você imprimir um objeto ou passá-lo para format,, str.formatou str, se um __str__método for definido, esse método será chamado, caso contrário, __repr__será usado.

__repr__

O __repr__método é chamado pela função embutida repre é o que é ecoado no shell python quando avalia uma expressão que retorna um objeto.

Como ele fornece um backup __str__, se você puder escrever apenas um, comece com__repr__

Aqui está a ajuda integrada sobre repr:

repr(...)
    repr(object) -> string

    Return the canonical string representation of the object.
    For most object types, eval(repr(object)) == object.

Ou seja, para a maioria dos objetos, se você digitar o que é impresso repr, poderá criar um objeto equivalente. Mas essa não é a implementação padrão.

Implementação padrão de __repr__

O objeto padrão __repr__é ( fonte C Python ) algo como:

def __repr__(self):
    return '<{0}.{1} object at {2}>'.format(
      self.__module__, type(self).__name__, hex(id(self)))

Isso significa que, por padrão, você imprimirá o módulo do qual o objeto é, o nome da classe e a representação hexadecimal de sua localização na memória - por exemplo:

<__main__.Foo object at 0x7f80665abdd0>

Essas informações não são muito úteis, mas não há como derivar como se pode criar com precisão uma representação canônica de qualquer instância, e é melhor que nada, pelo menos nos dizendo como podemos identificá-las exclusivamente na memória.

Como pode __repr__ser útil?

Vamos ver como isso pode ser útil, usando o shell e os datetimeobjetos Python . Primeiro, precisamos importar o datetimemódulo:

import datetime

Se chamarmos datetime.nowo shell, veremos tudo o que precisamos para recriar um objeto datetime equivalente. Isso é criado pela data __repr__e hora :

>>> datetime.datetime.now()
datetime.datetime(2015, 1, 24, 20, 5, 36, 491180)

Se imprimirmos um objeto datetime, veremos um bom formato legível por humanos (de fato, ISO). Isso é implementado pelo datetime __str__:

>>> print(datetime.datetime.now())
2015-01-24 20:05:44.977951

É simples recriar o objeto que perdemos porque não o atribuímos a uma variável, copiando e colando da __repr__saída, imprimindo-a e obtendo-a na mesma saída legível por humanos que o outro objeto:

>>> the_past = datetime.datetime(2015, 1, 24, 20, 5, 36, 491180)
>>> print(the_past)
2015-01-24 20:05:36.491180

Como eu os implemento?

Enquanto você está desenvolvendo, você poderá reproduzir objetos no mesmo estado, se possível. Por exemplo, é assim que o objeto datetime define __repr__( fonte Python ). É bastante complexo, devido a todos os atributos necessários para reproduzir esse objeto:

def __repr__(self):
    """Convert to formal string, for repr()."""
    L = [self._year, self._month, self._day,  # These are never zero
         self._hour, self._minute, self._second, self._microsecond]
    if L[-1] == 0:
        del L[-1]
    if L[-1] == 0:
        del L[-1]
    s = "%s.%s(%s)" % (self.__class__.__module__,
                       self.__class__.__qualname__,
                       ", ".join(map(str, L)))
    if self._tzinfo is not None:
        assert s[-1:] == ")"
        s = s[:-1] + ", tzinfo=%r" % self._tzinfo + ")"
    if self._fold:
        assert s[-1:] == ")"
        s = s[:-1] + ", fold=1)"
    return s

Se você deseja que seu objeto tenha uma representação legível por humanos, você pode implementar a __str__seguir. Veja como o objeto datetime ( fonte Python ) implementa __str__, o que é fácil porque ele já tem uma função para exibi-lo no formato ISO:

def __str__(self):
    "Convert to string, for str()."
    return self.isoformat(sep=' ')

Set __repr__ = __str__?

Esta é uma crítica de outra resposta aqui que sugere configuração __repr__ = __str__.

A configuração __repr__ = __str__é boba - __repr__é um substituto para __str__e um __repr__, escrito para uso dos desenvolvedores na depuração, deve ser escrito antes de você escrever um __str__.

Você precisa de um __str__somente quando precisar de uma representação textual do objeto.

Conclusão

Defina os __repr__objetos que você escreve para que você e outros desenvolvedores tenham um exemplo reproduzível ao usá-lo à medida que desenvolve. Defina __str__quando você precisa de uma representação de sequência legível por humanos.

Aaron Hall
fonte
Não deveria ser algo assim type(obj).__qualname__?
Solomon Ucko
@SolomonUcko: Sim, no Python 3, isso parece ser o caso - estou pesquisando o código-fonte em que isso está implementado e atualizarei minha resposta com essas informações quando reuni-las.
Aaron Hall
33

Na página 358 do livro Python scripting for science computational, de Hans Petter Langtangen, afirma claramente que

  • O __repr__objetivo é uma representação completa da string do objeto;
  • O __str__é retornar uma boa string para impressão.

Então, eu prefiro entendê-los como

  • repr = reproduzir
  • str = string (representação)

do ponto de vista do usuário, embora esse seja um mal-entendido que eu fiz ao aprender python.

Um pequeno mas bom exemplo também é dado na mesma página da seguinte maneira:

Exemplo

In [38]: str('s')
Out[38]: 's'

In [39]: repr('s')
Out[39]: "'s'"

In [40]: eval(str('s'))
Traceback (most recent call last):

  File "<ipython-input-40-abd46c0c43e7>", line 1, in <module>
    eval(str('s'))

  File "<string>", line 1, in <module>

NameError: name 's' is not defined


In [41]: eval(repr('s'))
Out[41]: 's'
Yong Yang
fonte
Está na pág. # 351
jiten
4
É meio enganoso referir-se a reprreprodução. É melhor pensar nisso como representar.
criar o seu alerta
31

Além de todas as respostas dadas, gostaria de acrescentar alguns pontos: -

1) __repr__()é chamado quando você simplesmente escreve o nome do objeto no console python interativo e pressiona enter.

2) __str__()é invocado quando você usa o objeto com a instrução print.

3) Caso __str__esteja faltando, imprima e qualquer função usando str()invoca__repr__() de objeto.

4) __str__()de contêineres, quando invocados, executarão o __repr__()método de seus elementos contidos.

5) str()chamado dentro __str__()poderia recorrer sem um caso base e erro na profundidade máxima da recursão.

6) __repr__()pode chamar o repr()que tentará evitar a recursão infinita automaticamente, substituindo um objeto já representado por ....

Mangu Singh Rajpurohit
fonte
14

Simplificando:

__str__é usado para mostrar uma representação de string do seu objeto para ser lida facilmente por outras pessoas.

__repr__é utilizado para mostrar uma representação em cadeia do objecto.

Digamos que eu queira criar uma Fractionclasse em que a representação de string de uma fração seja '(1/2)' e o objeto (classe Fraction) seja representado como 'Fraction (1,2)'

Assim, podemos criar uma classe Fraction simples:

class Fraction:
    def __init__(self, num, den):
        self.__num = num
        self.__den = den

    def __str__(self):
        return '(' + str(self.__num) + '/' + str(self.__den) + ')'

    def __repr__(self):
        return 'Fraction (' + str(self.__num) + ',' + str(self.__den) + ')'



f = Fraction(1,2)
print('I want to represent the Fraction STRING as ' + str(f)) # (1/2)
print('I want to represent the Fraction OBJECT as ', repr(f)) # Fraction (1,2)
Zer0
fonte
13

Com toda a honestidade, eval(repr(obj))nunca é usado. Se você se encontra usando, deve parar, porque evalé perigoso, e as cordas são uma maneira muito ineficiente de serializar seus objetos (usepickle vez disso).

Portanto, eu recomendaria a configuração __repr__ = __str__. A razão é que str(list)chama repros elementos (considero que essa é uma das maiores falhas de design do Python que não foi abordada pelo Python 3). Um real reprprovavelmente não será muito útil como a saída de print [your, objects].

Para qualificar isso, na minha experiência, o caso de uso mais útil da reprfunção é colocar uma string dentro de outra (usando a formatação da string). Dessa forma, você não precisa se preocupar com escapar aspas ou algo assim. Mas observe que não há nada evalacontecendo aqui.

asmeurer
fonte
19
Eu acho que isso está errado. O uso de eval(repr(obj))é um teste de sanidade e uma regra de ouro - se isso recriar o objeto original corretamente, você terá uma __repr__implementação decente . Não se pretende que você serialize objetos dessa maneira.
GTC
7
evalnão é inerentemente perigoso. Não é mais perigoso do que unlink, openou a gravar arquivos. Devemos parar de gravar em arquivos, porque talvez um ataque malicioso possa usar um caminho arbitrário para inserir conteúdo? Tudo é perigoso se usado de maneira burra por pessoas burras. A idiotice é perigosa. Os efeitos de Dunning-Kruger são perigosos. evalé apenas uma função.
Luis Masuelli
12

De um Wiki de referência do Python (não oficial) (cópia de arquivo) por effbot:

__str__" calcula a representação de string" informal "de um objeto. Isso difere de __repr__que não precisa ser uma expressão válida do Python: uma representação mais conveniente ou concisa pode ser usada. "

Casebash
fonte
3
__repr__não é de forma alguma necessário para retornar uma expressão Python vaild.
Físico Louco
10

str - Cria um novo objeto de string do objeto especificado.

repr - Retorna a representação de string canônica do objeto.

As diferenças:

str ():

  • torna o objeto legível
  • gera saída para o usuário final

repr ():

  • precisa de código que reproduza o objeto
  • gera saída para o desenvolvedor
Inconnu
fonte
8

Um aspecto que está faltando em outras respostas. É verdade que, em geral, o padrão é:

  • Objetivo de __str__: legível por humanos
  • Objetivo de __repr__: inequívoco, possivelmente legível por máquina viaeval

Infelizmente, essa diferenciação é falha, porque o Python REPL e também o IPython usam __repr__para imprimir objetos em um console REPL (consulte as perguntas relacionadas para Python e IPython ). Assim, projetos direcionados ao trabalho de console interativo (por exemplo, Numpy ou Pandas) começaram a ignorar as regras acima e, em vez disso, fornecem uma __repr__implementação legível por humanos .

bluenote10
fonte
7

Do livro Fluent Python :

Um requisito básico para um objeto Python é fornecer representações de string utilizáveis ​​em si, uma usada para depuração e registro e outra para apresentação aos usuários finais. É por isso que os
métodos especiais __repr__e __str__existem no modelo de dados.

Ijaz Ahmad Khan
fonte
5

Excelentes respostas já cobrem a diferença entre __str__e __repr__, o que para mim se resume ao fato de o primeiro ser legível até mesmo por um usuário final, e o último ser o mais útil possível para os desenvolvedores. Dado isso, acho que a implementação padrão __repr__geralmente falha em atingir esse objetivo porque omite informações úteis para os desenvolvedores.

Por esse motivo, se eu tiver um simples __str__, geralmente apenas tento obter o melhor dos dois mundos com algo como:

def __repr__(self):
    return '{0} ({1})'.format(object.__repr__(self), str(self))
orome
fonte
4

Uma coisa importante a ter em mente é que o contêiner __str__usa objetos contidos ' __repr__.

>>> from datetime import datetime
>>> from decimal import Decimal
>>> print (Decimal('52'), datetime.now())
(Decimal('52'), datetime.datetime(2015, 11, 16, 10, 51, 26, 185000))
>>> str((Decimal('52'), datetime.now()))
"(Decimal('52'), datetime.datetime(2015, 11, 16, 10, 52, 22, 176000))"

O Python favorece a ambiguidade sobre a legibilidade , a __str__chamada de a tuplechama de objetos contidos __repr__, a representação "formal" de um objeto. Embora a representação formal seja mais difícil de ler do que a informal, ela é inequívoca e mais robusta contra bugs.

zangw
fonte
Ele usa __repr__ quando ( __str__) não está definido! Então, você está errado.
jiten
4

Em poucas palavras:

class Demo:
  def __repr__(self):
    return 'repr'
  def __str__(self):
    return 'str'

demo = Demo()
print(demo) # use __str__, output 'str' to stdout

s = str(demo) # __str__ is used, return 'str'
r = repr(demo) # __repr__ is used, return 'repr'

import logging
logger = logging.getLogger(logging.INFO)
logger.info(demo) # use __str__, output 'str' to stdout

from pprint import pprint, pformat
pprint(demo) # use __repr__, output 'repr' to stdout
result = pformat(demo) # use __repr__, result is string which value is 'str'
ShadowWalker
fonte
4
>>> print(decimal.Decimal(23) / decimal.Decimal("1.05"))
21.90476190476190476190476190
>>> decimal.Decimal(23) / decimal.Decimal("1.05")
Decimal('21.90476190476190476190476190')

Quando print()é chamado, o resultado do decimal.Decimal(23) / decimal.Decimal("1.05")número bruto é impresso; essa saída está na forma de string que pode ser obtida com __str__(). Se simplesmente inserirmos a expressão, obtemos uma decimal.Decimalsaída - essa saída está na forma representacional que pode ser obtida com __repr__(). Todos os objetos Python têm duas formas de saída. O formato da string foi projetado para ser legível por humanos. A forma representacional é projetada para produzir resultados que, se alimentados a um intérprete Python, (quando possível) reproduziriam o objeto representado.

BattleDrum
fonte
4

__str__pode ser chamado em um objeto chamando str(obj)e deve retornar uma sequência legível por humanos.

__repr__ pode ser chamado em um objeto chamando repr(obj) e deve retornar um objeto interno (campos / atributos do objeto)

Este exemplo pode ajudar:

class C1:pass

class C2:        
    def __str__(self):
        return str(f"{self.__class__.__name__} class str ")

class C3:        
    def __repr__(self):        
         return str(f"{self.__class__.__name__} class repr")

class C4:        
    def __str__(self):
        return str(f"{self.__class__.__name__} class str ")
    def __repr__(self):        
         return str(f"{self.__class__.__name__} class repr")


ci1 = C1()    
ci2 = C2()  
ci3 = C3()  
ci4 = C4()

print(ci1)       #<__main__.C1 object at 0x0000024C44A80C18>
print(str(ci1))  #<__main__.C1 object at 0x0000024C44A80C18>
print(repr(ci1)) #<__main__.C1 object at 0x0000024C44A80C18>
print(ci2)       #C2 class str
print(str(ci2))  #C2 class str
print(repr(ci2)) #<__main__.C2 object at 0x0000024C44AE12E8>
print(ci3)       #C3 class repr
print(str(ci3))  #C3 class repr
print(repr(ci3)) #C3 class repr
print(ci4)       #C4 class str 
print(str(ci4))  #C4 class str 
print(repr(ci4)) #C4 class repr
prosti
fonte
3

Compreender __str__e__repr__ distinga-os intuitivamente e permanentemente.

__str__ retorna o corpo disfarçado de um determinado objeto para legível dos olhos
__repr__ possam ser retornar o corpo real de carne de um determinado objeto (retornar em si) para que a ambiguidade seja identificada.

Veja em um exemplo

In [30]: str(datetime.datetime.now())
Out[30]: '2017-12-07 15:41:14.002752'
Disguised in string form

Quanto a __repr__

In [32]: datetime.datetime.now()
Out[32]: datetime.datetime(2017, 12, 7, 15, 43, 27, 297769)
Presence in real body which allows to be manipulated directly.

Podemos realizar operações aritméticas de forma __repr__conveniente.

In [33]: datetime.datetime.now()
Out[33]: datetime.datetime(2017, 12, 7, 15, 47, 9, 741521)
In [34]: datetime.datetime(2017, 12, 7, 15, 47, 9, 741521) - datetime.datetime(2
    ...: 017, 12, 7, 15, 43, 27, 297769)
Out[34]: datetime.timedelta(0, 222, 443752)

se aplicar a operação em __str__

In [35]: '2017-12-07 15:43:14.002752' - '2017-12-07 15:41:14.002752'
TypeError: unsupported operand type(s) for -: 'str' and 'str'

Retorna nada além de erro.

Outro exemplo.

In [36]: str('string_body')
Out[36]: 'string_body' # in string form

In [37]: repr('real_body')
Out[37]: "'real_body'" #its real body hide inside

Espero que isso ajude a construir bases concretas para explorar mais respostas.

Cálculo
fonte
3
  1. __str__deve retornar o objeto string enquanto __repr__pode retornar qualquer expressão python.
  2. Se a __str__implementação estiver ausente, a __repr__função será usada como fallback. Não há fallback se a __repr__implementação da função estiver ausente.
  3. Se a __repr__função estiver retornando a representação String do objeto, podemos pular a implementação da __str__função.

Fonte: https://www.journaldev.com/22460/python-str-repr-functions

Sampath
fonte
2

__repr__é usado em qualquer lugar, exceto por printe strmétodos (quando a __str__é definido!)

techkuz
fonte