4
respostas

Não ficou claro como substituo __str__ por __repr__ , podem me ajudar?

class Programa: def init(self, nome, ano): self.nome = nome.title() self.ano = ano self.likes = 0

@property
def likes(self):
     return self._likes

def dar_like(self):
    self._likes += 1

@property
def nome(self):
    return self._nome

@nome.setter
def nome(self, novo_nome):
    self._nome = novo_nome.title()

def __str__(self):
    return f'{self._nome} - {self.ano} - {self._likes} Likes'

class Filme(Programa): def init(self, nome, ano, duracao): super().init(nome, ano) self.duracao = duracao

def __str__(self):
    return f'{self._nome} - {self.ano} - {self.duracao} min - {self._likes} Likes'

class Serie(Programa): def init(self, nome, ano, temporadas): super().init(nome, ano) self.temporadas = temporadas

def __str__(self):
    return f'{self._nome} - {self.ano} - {self.temporadas} temporadas - {self._likes} Likes'

vingadores = Filme('vingadores - guerra infinita', 2018, 160) vingadores.dar_like() atlanta = Serie('atlanta', 2018, 2) atlanta.dar_like() atlanta.dar_like()

filmes_e_series = [vingadores, atlanta]

for programa in filmes_e_series: print(programa)

4 respostas

Oi Luiz

Sua dúvida não ficou muito clara para mim, mas você não precisa "substituir" o __str__() pelo __repr__().

O que você está fazendo no seu código é subscrever o __str__ original já definido pelo python. Isso faz com que quando você chame a função print() ou str() retorne uma informação legível ao invés do endereço de memória que o objeto está armazenado, como era feito quando não havia sido subscrito o __str__().

O __repr__() faz a mesma coisa que o __str__(), pelo que eu saiba, porém as pessoas usam para coisas diferentes. Enquanto o __str__() é subscrito para devolver uma informação legível e "amigável", o __repr__() é subscrito para devolver algo mais técnico.

Para redefinir o __repr__() original que o python já traz definido, você faz a mesma coisa que fez com o __str__(). Mas não faz muita diferença um do outro. Os dois podem ser redenidos para imprimir o que você quiser.

Eu tentei ajudar, mas como não entendi sua dúvida direito, talvez não tenha respondido sua pergunta. Caso tenha sido o caso você pode perguntar de novo, eu tento ajudar :)

Opa, ao contrario do que o Ethan disse, __repr__() e __str__() não são a mesma coisa e nem fazem a mesma coisa. São usados para contextos e situações diferentes. Vou traduzir o que encontrei nesse post, mais específicamente esse comentario e parte desse e desse tambem.

Resumindo, o objetivo do __repr__ é não ter ambiguidade e do __str__ é poder ser lido.

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)'

Na documentação do repr:

repr(objeto)

Retorna uma string contendo uma representação printavel de um objeto. Isso é o mesmo valor gerado por conversões (crase). As vezes é util ser capaz de acessar essa operação como uma função ordinária. Para muitos tipos, essa função tenta retornar uma string que resulta em um objeto com o mesmo valor que quando passada pelo eval(), caso contrario a representação (repr) é uma string entre < e > que contem o nome do tipo do objeto junto com informações adicionais, geralmente incluindo o nome e endereço do objeto. Uma classe pode controlar o que essa função retorna para suas instancias ao definir pelo metodo __repr__().

Na documentação do str:

str(objeto='')

Retorna uma string contendo uma representação agradavelvel e printavel de um objeto. Para strings, isso retorna a própria string. A diferença entre repr(objeto) é que str(objeto) não tenta sempre retornar uma string que seja aceita no eval(); seu objetivo é retornar uma string printavel. Se nenhum argumento for dado, retorne uma string vazia, ''.

Conclusão:

Defina __repr__ nos seus objetos para que você e outros desenvolvedores tenham um exemplo reproduzivel quando usando a sua classe enquanto programa. Defina __str__ quando você precise de uma representação do seu objeto que seja legivel por humanos e em formato de string.

Outra coisa importante:

Se você definir o repr sem definir o str, por padrão, seu str vai ser seu repr. Agora se você definir apenas seu str, seu repr não vai ser definido.

>>> 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>
>>> 

Se quiser ler as partes que traduzi em ingles ta ai:

In short, the goal of repr is to be unambiguous and str is to be readable.

Read this documentation for repr:

repr(object) Return a string containing a printable representation of an object. This is the same value yielded by conversions (reverse quotes). It is sometimes useful to be able to access this operation as an ordinary function. For many types, this function makes an attempt to return a string that would yield an object with the same value when passed to eval(), otherwise the representation is a string enclosed in angle brackets that contains the name of the type of the object together with additional information often including the name and address of the object. A class can control what this function returns for its instances by defining a repr() method.

Here is the documentation for str:

str(object='') Return a string containing a nicely printable representation of an object. For strings, this returns the string itself. The difference with repr(object) is that str(object) does not always attempt to return a string that is acceptable to eval(); its goal is to return a printable string. If no argument is given, returns the empty string, ''.

Define repr for objects you write so you and other developers have a reproducible example when using it as you develop. Define str when you need a human readable string representation of it.

Luigi, muito obrigado pela correção!

Expliquei da forma que eu tinha entendido os dois, e na minha cabeça eles tinha funcionalidades idênticas. Vou procurar entender mais sobre esses dois métodos.

Nada Ethan, ta todo mundo aqui pra aprender! Se você souber ingles recomendo ir lendo a thread do stackOverFlow que eu coloquei na minha outra resposta. Tem bastante gente explicando como funciona, se você for juntando uma resposta com outra você consegue entender o conceito sem problema.