El objeto Python .__ repr __ (self) debería ser una expresión?

Estaba mirando los métodos de objetos incorporados en la documentación de Python , y estaba interesado en la documentación para el object.__repr__(self) . Esto es lo que dice:

Llamado por la función incorporada repr () y por las conversiones de cadena (comillas inversas) para calcular la representación de cadena “oficial” de un objeto. Si es posible, esto debería parecerse a una expresión de Python válida que podría usarse para recrear un objeto con el mismo valor (dado un entorno apropiado). Si esto no es posible, debe devolverse una cadena de la forma . El valor de retorno debe ser un objeto de cadena. Si una clase define repr () pero no str (), repr () también se usa cuando se requiere una representación de cadena “informal” de instancias de esa clase.

Esto se suele utilizar para la depuración, por lo que es importante que la representación sea rica en información y no sea ambigua.

La parte más interesante para mí, fue …

Si es posible, esto debería parecerse a una expresión de Python válida que podría usarse para recrear un objeto con el mismo valor

… pero no estoy seguro de lo que esto significa. Dice que debería parecerse a una expresión que se puede usar para recrear el objeto, pero eso significa que debería ser solo un ejemplo del tipo de expresión que podría usar, o si debería ser una expresión real, que se pueda ejecutar (eval etc.) para recrear el objeto? O … ¿debería ser solo un replanteamiento de la expresión real que se utilizó, con fines puramente informativos?

En general, estoy un poco confundido en cuanto a exactamente lo que debería poner aquí.

 >>> from datetime import date >>> >>> repr(date.today()) # calls date.today().__repr__() 'datetime.date(2009, 1, 16)' >>> eval(_) # _ is the output of the last command datetime.date(2009, 1, 16) 

La salida es una cadena que puede ser analizada por el intérprete de python y da como resultado un objeto igual.

Si eso no es posible, debería devolver una cadena en forma de <...some useful description...> .

Debe ser una expresión de Python que, cuando se evalúa, crea un objeto con exactamente las mismas propiedades que esta. Por ejemplo, si tiene una clase de Fraction que contiene dos enteros, un numerador y un denominador, su __repr__() se vería así:

 # in the definition of Fraction class def __repr__(self): return "Fraction(%d, %d)" % (self.numerator, self.denominator) 

Suponiendo que el constructor toma esos dos valores.

Guía: Si puede proporcionar de manera sucinta una representación exacta , formatéela como una expresión de Python (lo que implica que puede evaluarse y copiarse directamente en el código fuente, en el contexto correcto). Si proporciona una representación inexacta , use el formato <...> .

Hay muchas representaciones posibles para cualquier valor, pero la más interesante para los progtwigdores de Python es una expresión que recrea el valor. Recuerde que aquellos que entienden de Python son el público objective, y esa es la razón por la cual las representaciones inexactas deben incluir el contexto relevante. Incluso el , aunque es casi totalmente inútil, aún proporciona type, id() (para distinguir diferentes objetos), e indicación de que no hay una mejor representación disponible.

“pero ¿eso significa que debería ser solo un ejemplo del tipo de expresión que podría usar, o debería ser una expresión real, que se pueda ejecutar (eval etc.) para recrear el objeto? O … si debería ser ¿Solo una reescritura de la expresión real que se utilizó, con fines puramente informativos?

Wow, eso es un montón de retorcimiento de manos.

  1. Un “un ejemplo del tipo de expresión que podría usar” no sería una representación de un objeto específico. Eso no puede ser útil o significativo.

  2. ¿Cuál es la diferencia entre “una expresión real, que puede … recrear el objeto” y “una reescritura de la expresión real que se utilizó [para crear el objeto]”? Ambas son una expresión que crea el objeto. No hay distinción práctica entre estos. Una repetición de llamada podría producir una nueva expresión o la expresión original. En muchos casos, son lo mismo.

Tenga en cuenta que esto no siempre es posible, práctico o deseable.

En algunos casos, notará que repr () presenta una cadena que claramente no es una expresión de ningún tipo. La repr () predeterminada para cualquier clase que defina no es útil como expresión.

En algunos casos, es posible que tenga referencias mutuas (o circulares) entre objetos. El repr () de esa jerarquía enredada no puede tener sentido.

En muchos casos, un objeto se construye incrementalmente a través de un analizador. Por ejemplo, desde XML o JSON o algo así. ¿Cuál sería la reprimenda? ¿El XML original o JSON? Claramente no, ya que no son Python. Podría ser alguna expresión de Python que haya generado el XML. Sin embargo, para un documento XML gigantesco, podría no ser posible escribir una sola expresión de Python que fuera el equivalente funcional de analizar XML.

Para ver cómo funciona la reproducción dentro de una clase, ejecute el siguiente código, primero con y luego sin el método de reproducción .

 class Coordinate (object): def __init__(self,x,y): self.x = x self.y = y def getX(self): # Getter method for a Coordinate object's x coordinate. # Getter methods are better practice than just accessing an attribute directly return self.x def getY(self): # Getter method for a Coordinate object's y coordinate return self.y def __repr__(self): #remove this and the next line and re-run return 'Coordinate(' + str(self.getX()) + ',' + str(self.getY()) + ')' >>>c = Coordinate(2,-8) >>>print(c) 

‘repr’ significa representación. Primero, creamos una instancia de coordenada de clase.

 x = Coordinate(3, 4) 

Entonces, si ingresamos x en la consola, la salida es

 <__main__.Coordinate at 0x7fcd40ab27b8> 

Si utilizas repr ():

 >>> repr(x) Coordinate(3, 4) 

la salida es la misma que ‘Coordenadas (3, 4)’, excepto que es una cadena. Puede usarla para recrear una instancia de coordenadas.

En conclusión, repr () meathod es imprimir una cadena, que es la representación del objeto.

Creo que la confusión aquí radica en el inglés. Me refiero a __repr__() ; abreviatura de “representación” del valor que estoy adivinando, como dijo @ S.Lott

“¿Cuál es la diferencia entre” una expresión real, que puede … recrear el objeto “y” una conversión de la expresión real que se utilizó [para crear el objeto] “? Ambas son expresiones que crean el objeto. No hay distinción práctica entre estos. Una repetición de llamada podría producir una nueva expresión o la expresión original. En muchos casos, son lo mismo “.

Pero en algunos casos pueden ser diferentes. P.ej; puntos de coordenadas, es posible que desee que c.coordinate regrese: 3,5 pero c.__repr__ para devolver Coordinate(3, 5) . Espero que eso tenga más sentido…