¿Cuál es la diferencia entre __str__ y __repr__?

Cuál es la diferencia entre __str__ y __repr__ en Python?

preguntado el 17 de septiembre de 09 a las 01:09

24 Respuestas

Alex resumido bien pero, sorprendentemente, fue demasiado conciso.

Primero, permítame reiterar los puntos principales en Publicación de Alex:

  • La implementación predeterminada es inútil (es difícil pensar en una que no lo sea, pero sí)
  • __repr__ el objetivo es ser inequívoco
  • __str__ el objetivo es ser legible
  • Contenedor __str__ utiliza objetos contenidos ' __repr__

La implementación predeterminada es inútil

Esto es principalmente una sorpresa porque los valores predeterminados de Python tienden a ser bastante útiles. Sin embargo, en este caso, tener un valor predeterminado para __repr__ que actuaría como:

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

habría sido demasiado peligroso (por ejemplo, demasiado fácil entrar en una recursividad infinita si los objetos se referencian entre sí). Entonces Python sale de la policía. Tenga en cuenta que hay un valor predeterminado que es verdadero: si __repr__ está definido, y __str__ no lo es, el objeto se comportará como si __str__=__repr__.

Esto significa, en términos simples: casi todos los objetos que implemente deben tener una función __repr__ que se puede utilizar para comprender el objeto. Implementar __str__ es opcional: hágalo si necesita una funcionalidad de "impresión bonita" (por ejemplo, utilizada por un generador de informes).

El objetivo de la __repr__ es ser inequívoco

Permítanme decirlo directamente: no creo en los depuradores. Realmente no sé cómo usar ningún depurador y nunca lo he usado en serio. Además, creo que la gran falla de los depuradores es su naturaleza básica: la mayoría de las fallas que depuro ocurrieron hace mucho, mucho tiempo, en una galaxia muy lejana. Esto significa que creo, con fervor religioso, en la tala. El registro es el elemento vital de cualquier sistema de servidor decente de "disparar y olvidar". Python facilita el registro: tal vez con algunos contenedores específicos del proyecto, todo lo que necesita es un

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)

Pero tiene que hacer el último paso: asegúrese de que cada objeto que implemente tenga una reproducción útil, para que un código como ese simplemente funcione. Por eso surge la cuestión de la "evaluación": si tienes suficiente información, eval(repr(c))==c, eso significa que sabes todo lo que hay que saber sobre c. Si eso es lo suficientemente fácil, al menos de una manera difusa, hágalo. Si no es así, asegúrese de tener suficiente información sobre c de todas formas. Normalmente uso un formato similar a eval: "MyClass(this=%r,that=%r)" % (self.this,self.that). No significa que realmente pueda construir MyClass, o que esos sean los argumentos correctos del constructor, pero es una forma útil para expresar “esto es todo lo que necesita saber sobre esta instancia”.

Nota: usé %r arriba, no %s. Siempre quieres usar repr() [o %r carácter de formato, equivalentemente] dentro __repr__ implementación, o está derrotando el objetivo de repr. Quieres poder diferenciarte MyClass(3) y MyClass("3").

El objetivo de la __str__ debe ser legible

Específicamente, no se pretende que sea inequívoco; tenga en cuenta que str(3)==str("3"). Del mismo modo, si implementa una abstracción de IP, hacer que su str se vea como 192.168.1.1 está bien. Cuando se implementa una abstracción de fecha / hora, el str puede ser "2010/4/12 15:35:22", etc. El objetivo es representarlo de una manera que un usuario, no un programador, quiera leerlo. Elimine los dígitos inútiles, pretenda ser otra clase; siempre que sea compatible con la legibilidad, es una mejora.

Contenedor __str__ utiliza objetos contenidos ' __repr__

Esto parece sorprendente, ¿no? Es un poco, pero ¿qué tan legible sería si usara su __str__?

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

No muy. Específicamente, las cadenas de un contenedor encontrarían demasiado fácil alterar su representación de cadena. Ante la ambigüedad, recuerde, Python resiste la tentación de adivinar. Si desea el comportamiento anterior cuando imprime una lista, simplemente

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

(Probablemente también pueda averiguar qué hacer con los diccionarios.

Resumen

Implementar __repr__ para cualquier clase que implementes. Esto debería ser una segunda naturaleza. Implementar __str__ si cree que sería útil tener una versión de cadena que se equivoque en el lado de la legibilidad.

Respondido el 21 de diciembre de 19 a las 04:12

Definitivamente no estoy de acuerdo con su opinión de que la depuración no es el camino a seguir. Para el desarrollo, utilice un depurador (y / o registro), para el registro de uso de producción. Con un depurador tiene una vista de todo lo que salió mal cuando ocurrió el problema. Puedes ver la imagen completa. A menos que esté registrando TODO, no puede obtener eso. Además, si está registrando todo, tendrá que navegar a través de toneladas de datos para obtener lo que desea. - Samuel

Gran respuesta (excepto el bit sobre no usar depuradores). Solo me gustaría agregar un enlace a esto. otras preguntas y respuestas sobre str vs Unicode en Python 3 lo que podría ser relevante para la discusión de las personas que han realizado el cambio. - EsoAintTrabajando

plus1 para depuradores son inútiles y no se escalan ni un centavo. En su lugar, aumente su rendimiento de registro. Y sí, esta fue una publicación bien escrita. Resulta __repr__ era lo que necesitaba para depurar. Gracias por tu ayuda. - nube_personal

Dejando a un lado la locura del depurador, aprendí el% r y vale la pena votar de todos modos. mickey perlstein

en depurador vs no depurador: no obtenga opiniones tan arraigadas. En algunas aplicaciones, la depuración no es realista, generalmente cuando se trata de tiempo real o cuando su código solo se ejecuta de forma remota en una plataforma con poco acceso o sin consola. En la mayoría de los otros casos, será mucho más rápido detenerse en una excepción para investigar o establecer un punto de interrupción, porque no tiene que pasar por miles de líneas de registro (lo que saturará su disco y ralentizará la aplicación). Por último, no siempre es posible iniciar sesión, por ejemplo, en dispositivos integrados, el depurador también es tu amigo. - Glifo rojo

Mi regla de oro: __repr__ es para desarrolladores, __str__ es para clientes.

Respondido el 17 de Septiembre de 09 a las 12:09

Esto es cierto porque para obj = uuid.uuid1 (), obj .__ str __ () es "2d7fc7f0-7706-11e9-94ae-0242ac110002" y obj .__ repr __ () es "UUID ('2d7fc7f0-7706-11e9-94ae-0242 ') ". Los desarrolladores necesitan (valor + origen) mientras que los clientes necesitan un valor y no les importa cómo lo obtuvieron. - Naren Yellavula

Aquí cliente puede no significar necesariamente el usuario final. Es el cliente o usuario del objeto. Entonces, si es un SDK, los desarrolladores de SDK usarán __str__ por lo que los desarrolladores normales tienen un objeto legible. Por otro lado, __repr__ es para los propios desarrolladores del SDK. - Shiplu Mokadim

A menos que actúe específicamente para asegurarse de lo contrario, la mayoría de las clases no tienen resultados útiles para:

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

Como puede ver, no hay diferencia y no hay información más allá de la clase y el objeto. id. Si solo anula uno de los dos ...:

>>> 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 ves, si anulas __repr__, que TAMBIÉN se usa para __str__, pero no al revés.

Otros datos cruciales para saber: __str__ en un contenedor incorporado utiliza el __repr__, No la __str__, por los elementos que contiene. Y, a pesar de las palabras sobre el tema que se encuentran en los documentos típicos, casi nadie se molesta en hacer el __repr__ de objetos sea una cadena que eval puede usar para construir un objeto igual (es demasiado difícil, Y no saber cómo se importó realmente el módulo relevante lo hace realmente imposible).

Entonces, mi consejo: concéntrate en hacer __str__ razonablemente legible por humanos, y __repr__ tan inequívoco como sea posible, incluso si eso interfiere con el objetivo difuso e inalcanzable de hacer __repr__Valor devuelto aceptable como entrada para __eval__!

Respondido el 17 de Septiembre de 09 a las 05:09

En mis pruebas unitarias siempre verifico que eval(repr(foo)) evalúa a un objeto igual a foo. Tiene razón en que no funcionará fuera de mis casos de prueba, ya que no sé cómo se importa el módulo, pero esto al menos garantiza que funcione en algo contexto predecible. Creo que esta es una buena forma de evaluar si el resultado de __repr__ es lo suficientemente explícito. Hacer esto en una prueba unitaria también ayuda a garantizar que __repr__ sigue los cambios en la clase. - steven t snyder

Siempre trato de asegurarme de que eval(repr(spam)) == spam (al menos en el contexto correcto), o eval(repr(spam)) plantea un SyntaxError. De esa forma evitará confusiones. (Y eso es casi verdadero para los builtins y la mayoría de stdlib, excepto para, por ejemplo, listas recursivas, donde a=[]; a.append(a); print(eval(repr(a))) te dio [[Ellipses]]…) Por supuesto que no hago eso para utilizan el eval(repr(spam)), excepto como un chequeo de cordura en las pruebas unitarias ... pero yo do a veces copiar y pegar repr(spam) en una sesión interactiva. - abarnert

¿Por qué no utilizarían los contenedores (listas, tuplas) __str__ para cada elemento en lugar de __repr__? Me parece simplemente incorrecto, ya que implementé un código legible. __str__ en mi objeto y cuando es parte de una lista veo el mas feo __repr__ en lugar de. - SuperGeo

Me encontré con un error molesto relacionado con el hecho de que eval(repr(x)) falla incluso para los tipos integrados: class A(str, Enum): X = 'x' generará SyntaxError en eval(repr(A.X)). Es triste, pero comprensible. POR CIERTO, eval(str(A.X)) realmente funciona, pero por supuesto solo si class A está dentro del alcance, por lo que probablemente no sea muy útil. - max

@SuperGeo Otras respuestas cubren esto: contenedor str elemento de uso repr porque [1, 2, 3] != ["1", "2, 3"]. - mtraceur

__repr__: la representación del objeto python generalmente eval lo convertirá de nuevo a ese objeto

__str__: es lo que crees que es ese objeto en forma de texto

p.ej

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

Respondido 15 ago 12, 20:08

En resumen, el objetivo de __repr__ es ser inequívoco y __str__ debe ser legible.

He aquí un buen ejemplo:

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

Lea esta documentación para repr:

repr(object)

Devuelve una cadena que contiene una representación imprimible de un objeto. Este es el mismo valor obtenido por las conversiones (comillas inversas). A veces es útil poder acceder a esta operación como una función normal. Para muchos tipos, esta función intenta devolver una cadena que produciría un objeto con el mismo valor cuando se pasa a eval(), de lo contrario, la representación es una cadena encerrada entre corchetes angulares que contiene el nombre del tipo de objeto junto con información adicional que a menudo incluye el nombre y la dirección del objeto. Una clase puede controlar lo que devuelve esta función para sus instancias definiendo un __repr__() método.

Aquí está la documentación para str:

str(object='')

Devuelve una cadena que contiene una representación agradablemente imprimible de un objeto. En el caso de las cadenas, devuelve la propia cadena. La diferencia con repr(object) es que str(object) no siempre intenta devolver una cadena que sea aceptable para eval(); su objetivo es devolver una cadena imprimible. Si no se proporciona ningún argumento, devuelve la cadena vacía, ''.

Respondido 28 Oct 13, 00:10

¿Cuál es el significado de cadena imprimible aquí? ¿Puedes explicarlo por favor? - vicrobot

basándonos en el ejemplo anterior de "bitoffdev" y @deadly, podemos ver cómo str es para el usuario final porque solo nos da una cadena legible donde como repetir es para desarrolladores porque nos da tanto el valor como el tipo. Si está buscando respuestas para entrevistas, sería perfecto. - PSK0007

Cuál es la diferencia entre __str__ y __repr__ en Python?

__str__ (lea como "cadena dunder (doble subrayado)") y __repr__ (leído como "dunder-repper" (para "representación")) son métodos especiales que devuelven cadenas en función del estado del objeto.

__repr__ proporciona un comportamiento de respaldo si __str__ no se encuentra.

Entonces, primero se debe escribir un __repr__ que le permite reinstalar un objeto equivalente de la cadena que devuelve, por ejemplo, usando eval o escribiéndolo carácter por carácter en un shell de Python.

En cualquier momento posterior, se puede escribir un __str__ para una representación de cadena legible por el usuario de la instancia, cuando uno crea que es necesario.

__str__

Si imprime un objeto o lo pasa a format, str.formato str, entonces si un __str__ método está definido, ese método será llamado, de lo contrario, __repr__ se utilizará.

__repr__

Los programas __repr__ el método es llamado por la función incorporada repr y es lo que se repite en su shell de Python cuando evalúa una expresión que devuelve un objeto.

Dado que proporciona una copia de seguridad para __str__, si solo puede escribir uno, comience con __repr__

Aquí está la ayuda incorporada sobre repr:

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

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

Es decir, para la mayoría de los objetos, si escribe lo que está impreso por repr, debería poder crear un objeto equivalente. Pero esta no es la implementación predeterminada.

Implementación predeterminada de __repr__

El objeto predeterminado __repr__ es (Fuente C Python) algo como:

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

Eso significa que, de forma predeterminada, imprimirá el módulo del que proviene el objeto, el nombre de la clase y la representación hexadecimal de su ubicación en la memoria, por ejemplo:

<__main__.Foo object at 0x7f80665abdd0>

Esta información no es muy útil, pero no hay forma de derivar cómo se puede crear con precisión una representación canónica de una instancia dada, y es mejor que nada, al menos decirnos cómo podríamos identificarla de manera única en la memoria.

¿Cómo se puede controlar __repr__ ¿sé útil?

Veamos qué tan útil puede ser, usando el shell de Python y datetime objetos. Primero necesitamos importar el datetime módulo:

import datetime

Si llamamos datetime.now en el shell, veremos todo lo que necesitamos para recrear un objeto de fecha y hora equivalente. Esto es creado por la fecha y hora __repr__:

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

Si imprimimos un objeto de fecha y hora, vemos un buen formato legible por humanos (de hecho, ISO). Esto es implementado por datetime __str__:

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

Es muy sencillo recrear el objeto que perdimos porque no lo asignamos a una variable copiando y pegando desde el __repr__ salida, y luego imprimiéndola, y la obtenemos en la misma salida legible por humanos que el otro objeto:

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

¿Cómo los implemento?

A medida que desarrolle, querrá poder reproducir objetos en el mismo estado, si es posible. Así, por ejemplo, es como define el objeto de fecha y hora __repr__ (Fuente de Python). Es bastante complejo, debido a todos los atributos necesarios para reproducir tal 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

Si desea que su objeto tenga una representación más legible por humanos, puede implementar __str__ Siguiente. Así es como el objeto de fecha y hora (Fuente de Python) implementos __str__, lo que hace fácilmente porque ya tiene una función para mostrarlo en formato ISO:

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

Kit __repr__ = __str__?

Esta es una crítica de otra respuesta aquí que sugiere establecer __repr__ = __str__.

Fijar __repr__ = __str__ es tonto - __repr__ es una alternativa para __str__ y __repr__, escrito para el uso de desarrolladores en la depuración, debe escribirse antes de escribir un __str__.

Tu necesitas un __str__ solo cuando necesite una representación textual del objeto.

Conclusión

Definir __repr__ para los objetos que escribe para que usted y otros desarrolladores tengan un ejemplo reproducible al usarlo a medida que desarrolla. Definir __str__ cuando necesite una representación de cadena legible por humanos.

Respondido el 02 de junio de 19 a las 12:06

¿No debería ser algo parecido a type(obj).__qualname__? - Salomón Ucko

@SolomonUcko sí en Python 3, ese parece ser el caso: he estado buscando el código fuente donde se implementa esto y actualizaré mi respuesta con esa información cuando la obtenga. - Aaron Hall ♦

En la página 358 del libro Secuencias de comandos de Python para la ciencia computacional por Hans Petter Langtangen, establece claramente que

  • Los programas __repr__ apunta a una representación de cadena completa del objeto;
  • Los programas __str__ es devolver una bonita cadena para imprimir.

Entonces, prefiero entenderlos como

  • repr = reproducir
  • str = string (representación)

desde el punto de vista del usuario, aunque este es un malentendido que hice al aprender Python.

También se da un ejemplo pequeño pero bueno en la misma página de la siguiente manera:

Ejemplo

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'

Respondido el 19 de junio de 19 a las 08:06

Está en la pág. # 351. - jiten

Es un poco engañoso referirse a repr como reproducir. Es mejor pensar en ello como una representación. - NelsonGon

Aparte de todas las respuestas dadas, me gustaría agregar algunos puntos: -

1) __repr__() se invoca cuando simplemente escribe el nombre del objeto en la consola interactiva de Python y presiona enter.

2) __str__() se invoca cuando utiliza un objeto con una declaración de impresión.

3) En caso, si __str__ falta, luego imprima y cualquier función usando str() invoca __repr__() de objeto.

4) __str__() de contenedores, cuando se invoca se ejecutará __repr__() método de sus elementos contenidos.

5) str() llamado dentro __str__() potencialmente podría recurrir sin un caso base y error en la profundidad máxima de recursividad.

6) __repr__() puede llamar repr() que intentará evitar la recursividad infinita automáticamente, reemplazando un objeto ya representado con ....

Respondido el 05 de junio de 18 a las 08:06

Para hacerlo mas simple:

__str__ se utiliza para mostrar una representación de cadena de su objeto para ser leído fácilmente por otros.

__repr__ se utiliza para mostrar una representación de cadena de el objeto.

Digamos que quiero crear un Fraction clase donde la representación de cadena de una fracción es '(1/2)' y el objeto (clase Fraction) debe representarse como 'Fraction (1,2)'

Entonces podemos crear una clase Fraction simple:

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)

Respondido 28 Jul 16, 05:07

Con toda honestidad, eval(repr(obj)) nunca se usa. Si se encuentra usándolo, debe dejar de hacerlo, porque eval es peligroso, y las cadenas son una forma muy ineficiente de serializar sus objetos (use pickle en lugar).

Por lo tanto, recomendaría configurar __repr__ = __str__. La razón es que str(list) llamadas repr en los elementos (considero que este es uno de los mayores defectos de diseño de Python que no fue abordado por Python 3). Un real repr probablemente no será muy útil ya que el resultado de print [your, objects].

Para calificar esto, en mi experiencia, el caso de uso más útil de la repr La función es poner una cadena dentro de otra cadena (usando formato de cadena). De esta manera, no tiene que preocuparse por escapar de las comillas ni nada. Pero tenga en cuenta que no hay eval sucediendo aquí

Respondido 14 Abr '15, 01:04

Creo que esto pierde el sentido. El uso de eval(repr(obj)) es una prueba de cordura y una regla empírica: si esto recrea el objeto original correctamente, entonces tienes un buen __repr__ implementación. No se pretende que realmente serialice objetos de esta manera. - JWG

eval no es intrínsecamente peligroso. No es mas peligroso que unlink, openo escribir en archivos. ¿Deberíamos dejar de escribir en archivos porque quizás un ataque malintencionado podría usar una ruta de archivo arbitraria para colocar contenido dentro? Todo es peligroso si la gente tonta lo usa tontamente. La idiotez es peligrosa. Los efectos de Dunning-Kruger son peligrosos. eval es solo una función. - luis masuelli

De una Wiki de referencia de Python (no oficial) (copia de archivo) por effbot:

__str__ "calcula la representación de cadena "informal" de un objeto. Esto difiere de __repr__ ya que no tiene que ser una expresión de Python válida: en su lugar, se puede usar una representación más conveniente o concisa."

contestado el 29 de mayo de 19 a las 13:05

__repr__ de ninguna manera es necesario para devolver una expresión de Python válida. - Físico loco

str : Crea un nuevo objeto de cadena a partir del objeto dado.

repr - Devuelve la representación de cadena canónica del objeto.

Las diferencias:

str ():

  • hace que el objeto sea legible
  • genera resultados para el usuario final

repr ():

  • necesita código que reproduzca el objeto
  • genera salida para el desarrollador

Respondido el 04 de diciembre de 16 a las 16:12

Un aspecto que falta en otras respuestas. Es cierto que en general el patrón es:

  • Objetivo de __str__: legible por humanos
  • Objetivo de __repr__: inequívoco, posiblemente legible por máquina a través de eval

Desafortunadamente, esta diferenciación es defectuosa, porque Python REPL y también IPython usan __repr__ para imprimir objetos en una consola REPL (consulte las preguntas relacionadas para Python y IPython). Por lo tanto, los proyectos que están destinados al trabajo de consola interactiva (por ejemplo, Numpy o Pandas) han comenzado a ignorar las reglas anteriores y proporcionar una lectura humana __repr__ implementación en su lugar.

contestado el 26 de mayo de 17 a las 13:05

Del libro Pitón fluido:

Un requisito básico para un objeto Python es proporcionar representaciones de cadena utilizables de sí mismo, una utilizada para depurar y registrar, otra para la presentación a los usuarios finales. Es por eso que el
métodos especiales __repr__ y __str__ existen en el modelo de datos.

contestado el 29 de mayo de 19 a las 13:05

Excelentes respuestas ya cubren la diferencia entre __str__ y __repr__, que para mí se reduce a que el primero es legible incluso por un usuario final, y el segundo es lo más útil posible para los desarrolladores. Dado eso, encuentro que la implementación predeterminada de __repr__ a menudo no logra este objetivo porque omite información útil para los desarrolladores.

Por esta razón, si tengo un simple __str__, Generalmente trato de obtener lo mejor de ambos mundos con algo como:

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

Respondido 25 Abr '18, 20:04

Una cosa importante a tener en cuenta es que el contenedor __str__ utiliza objetos contenidos ' __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))"

Python favorece la falta de ambigüedad sobre la legibilidad, la __str__ llamada de un tuple llama a los objetos contenidos ' __repr__, la "formal" representación de un objeto. Aunque la representación formal es más difícil de leer que una informal, es inequívoca y más robusta contra los errores.

respondido 16 nov., 15:03

Utiliza __repr__ cuando (__str__ ) ¡no está definido! Entonces, estás equivocado. - jiten

En una palabra:

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'

Respondido 16 Abr '18, 10:04

>>> print(decimal.Decimal(23) / decimal.Decimal("1.05"))
21.90476190476190476190476190
>>> decimal.Decimal(23) / decimal.Decimal("1.05")
Decimal('21.90476190476190476190476190')

Cuándo print() se llama sobre el resultado de decimal.Decimal(23) / decimal.Decimal("1.05") se imprime el número sin procesar; esta salida está en forma de cadena que se puede lograr con __str__(). Si simplemente ingresamos la expresión obtenemos un decimal.Decimal salida: esta salida está en forma representativa que se puede lograr con __repr__(). Todos los objetos de Python tienen dos formas de salida. La forma de cadena está diseñada para ser legible por humanos. La forma de representación está diseñada para producir una salida que, si se envía a un intérprete de Python, reproduciría (cuando sea posible) el objeto representado.

contestado el 29 de mayo de 19 a las 13:05

__str__ se puede invocar en un objeto llamando str(obj) y debe devolver una cadena legible por humanos.

__repr__ se puede invocar en un objeto llamando repr(obj) y debe devolver el objeto interno (campos / atributos del objeto)

Este ejemplo puede ayudar:

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

Respondido el 06 de junio de 19 a las 17:06

Q: Cuál es la diferencia entre __str__() y __repr__()?

TL; DR: Diferencias entre str () / repr () y __str __ () / __ repr __ ()

LARGO

Esta pregunta ha existido por mucho tiempo, y hay una variedad de respuestas de las cuales la mayoría son correctas (sin mencionar las de varias leyendas de la comunidad de Python [!]). Sin embargo, cuando se trata del meollo del asunto, esta pregunta es análoga a preguntar por la diferencia entre los str() y repr() funciones integradas. Voy a describir las diferencias con mis propias palabras (lo que significa que puedo estar "tomando prestado" generosamente de Programación Core Python así que por favor perdóname).

Ambos str() y repr() tienen el mismo trabajo básico: su objetivo es devolver una representación de cadena de un objeto Python. Qué tipo de la representación de cadenas es lo que los diferencia.

  • str() & __str()__ devolver un imprimible representación de cadena de un objeto ... algo legible por humanos / para consumo humano
  • repr() & __repr()__ devolver una representación de cadena de un objeto que es un objeto Python válido, algo a lo que puedas pasar eval() o escriba en el shell de Python sin obtener un error.

Por ejemplo, asignemos una cadena a x y una int a y:

>>> x, y = 'foo', 123
>>> str(x), str(y)
('foo', '123')

¿Podemos tomar lo que está dentro de las comillas e ingresarlas textualmente en el intérprete de Python?

>>> 123
123
>>> foo
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'foo' is not defined

Claramente puedes por un int pero no necesariamente para un str. Mientras pueda pasar '123' a eval(), eso no funciona para 'foo':

>>> eval('123')
123
>>> eval('foo')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 1, in <module>
NameError: name 'foo' is not defined

Ahora intentemos repr(); de nuevo, descargue lo que hay en el par de comillas para cada cadena:

>>> repr(x), repr(y)
("'foo'", '123')
>>> 123
123
>>> 'foo'
'foo'

Wow, ellos ambas ¿trabaja? Eso es porque 'foo', mientras que una representación de cadena imprimible de esa cadena, es no evaluable, pero "'foo'" . 123 es un Python válido int llamado por cualquiera str() or repr(). Que pasa cuando llamamos eval() ¿con estos?

>>> eval('123')
123
>>> eval("'foo'")
'foo'

Funciona porque 123 y 'foo' son objetos de Python válidos. Otra conclusión clave es que, si bien a veces ambos devuelven lo mismo (la misma representación de cadena), no siempre es así. (Y sí, sí, puedo crear una variable foo donde el eval() funciona, pero ese no es el punto).

Más datos sobre ambos pares

  1. A veces, str() y repr() son llamados implícitamente, lo que significa que se llaman en nombre de los usuarios: cuando los usuarios ejecutan print (Py1 / Py2) o llame print() (Py3 +), incluso si los usuarios no llaman str() explícitamente, dicha llamada se realiza en su nombre antes de que se muestre el objeto.
  2. En el shell de Python (intérprete interactivo), si ingresa una variable en el >>> y presione RETORNO, el intérprete muestra los resultados de repr() implícitamente llamado a ese objeto.
  3. Para conectar str() y repr() a __str__() y __repr__(), darse cuenta de que las llamadas a las funciones integradas, es decir, str(x) or repr(y) resulta en llamar a los métodos especiales correspondientes de su objeto: x.__str__() or y.__repr()__
  4. Implementando __str__() y __repr__() por sus Clases de Python, sobrecargas las funciones integradas (str() y repr()), permitiendo que las instancias de tus clases se pasen a str() y repr(). Cuando se hacen tales llamadas, se dan la vuelta y llaman a la clase ' __str__() y __repr__() (por # 3).

Respondido el 07 de diciembre de 20 a las 19:12

Comprender __str__ y __repr__ distinguirlos intuitiva y permanentemente.

__str__ devolver el cuerpo disfrazado de cadena de un objeto dado para que los ojos lo puedan leer
__repr__ devolver el cuerpo de carne real de un objeto dado (volver a sí mismo) para identificar sin ambigüedad.

Míralo en un ejemplo

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

en cuanto 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 hacer operaciones aritméticas en __repr__ resultados convenientemente.

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)

si aplica la operación en __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'

Devuelve nada más que error.

Otro ejemplo.

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 esto te ayude a construir terrenos concretos para explorar más respuestas.

Respondido el 02 de enero de 18 a las 10:01

  1. __str__ debe devolver un objeto de cadena mientras que __repr__ puede devolver cualquier expresión de Python.
  2. If __str__ falta la implementación entonces __repr__ La función se utiliza como respaldo. No hay respaldo si __repr__ Falta la implementación de la función.
  3. If __repr__ función devuelve la representación de cadena del objeto, podemos omitir la implementación de __str__ función.

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

Respondido 18 Abr '19, 12:04

__repr__ se usa en todas partes, excepto por print y str métodos (cuando un __str__se define !)

Respondido 14 Abr '19, 08:04

Todo objeto hereda __repr__ de la clase base que crearon todos los objetos.

class Person:
     pass

p=Person()

si llamas repr(p) obtendrá esto por defecto:

 <__main__.Person object at 0x7fb2604f03a0>

Pero si llamas str(p) obtendrá el mismo resultado. es porque cuando __str__ no existe, Python llama __repr__

Implementemos el nuestro __str__

class Person:
    def __init__(self,name,age):
        self.name=name
        self.age=age
    def __repr__(self):
        print("__repr__ called")
        return f"Person(name='{self.name}',age={self.age})"

p=Person("ali",20)

print(p) y str(p)regresará

 __repr__ called
     Person(name='ali',age=20)

agreguemos __str__()

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age
        
    def __repr__(self):
        print('__repr__ called')
        return f"Person(name='{self.name}, age=self.age')"
    
    def __str__(self):
        print('__str__ called')
        return self.name

p=Person("ali",20)

si llamamos print(p) y str (p), llamará __str__() así volverá

__str__ called
ali

repr(p) regresará

repetir llamado "Persona (nombre = 'ali, edad = self.age')"

Vamos a omitir __repr__ y solo implementar __str__.

class Person:
def __init__(self, name, age):
    self.name = name
    self.age = age

def __str__(self):
    print('__str__ called')
    return self.name

p=Person('ali',20)

print(p) buscará el __str__ y volverá:

__str__ called
ali

NOTA = si tuviéramos __repr__ y __str__ definido, f'name is {p}' llamaría __str__

Respondido el 06 de diciembre de 20 a las 03:12

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.