python__repr__
El objeto Python.__ repr__(self) ¿debería ser una expresión? (6)
Estaba viendo los métodos de objetos incorporados en la documentación de Python , y estaba interesado en la documentación del object.__repr__(self)
. Esto es lo que dice:
Llamada 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, debería parecer 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, se debe devolver una cadena de la forma <... alguna descripción útil ...>. El valor de retorno debe ser un objeto de cadena. Si una clase define repr () pero no str (), entonces 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 ambigua.
La parte más interesante para mí fue ...
Si es posible, debería parecer 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 exactamente. Dice que debería verse como una expresión que puede usarse para recrear el objeto, 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 puede ejecutar (eval etc.) para recrear el objeto? O ... ¿debería ser simplemente un cambio de fase de la expresión real que se utilizó, con fines puramente informativos?
En general, estoy un poco confundido sobre exactamente lo que debería poner aquí.
"¿pero eso quiere decir que debería ser solo un ejemplo del tipo de expresión que podrías usar, o debería ser una expresión real, que se puede ejecutar (eval, etc.) para recrear el objeto? O ... ¿debería ser? solo un cambio de fase de la expresión real que se utilizó, con fines puramente informativos? "
Wow, eso es un montón de retorcerse las manos.
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.
¿Cuál es la diferencia entre "una expresión real, que puede ... recrear el objeto" y "un cambio de fase 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 llamada repetida 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. El repr () predeterminado para cualquier clase que defina no es útil como expresión.
En algunos casos, puede tener referencias mutuas (o circulares) entre objetos. La repr () de esa jerarquía enredada no puede tener sentido.
En muchos casos, un objeto se crea de forma incremental a través de un analizador. Por ejemplo, de XML o JSON o algo. ¿Cuál sería la respuesta? ¿El original XML o JSON? Claramente no, ya que no son Python. Podría ser alguna expresión de Python que generó 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.
Creo que la confusión aquí proviene del inglés. Quiero decir __repr__()
; abreviatura de ''representación'' del valor que estoy adivinando, como @ S.Lott dijo
"¿Cuál es la diferencia entre" una expresión real, que puede ... recrear el objeto "y" un cambio de fase 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 llamada repetida 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...
Debe ser una expresión de Python que, cuando se evalúa, crea un objeto con exactamente las mismas propiedades que este. Por ejemplo, si tiene una clase 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.
Para ver cómo funciona la repr dentro de una clase, ejecute el siguiente código, primero con y luego sin el método repr .
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)
Pauta: si puede proporcionar una representación exacta , formatéelo 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 que es más interesante para los programadores de Python es una expresión que recrea el valor. Recuerde que aquellos que entienden Python son el público objetivo, y por eso las representaciones inexactas deben incluir un contexto relevante. Incluso el <XXX object at 0xNNN>
predeterminado <XXX object at 0xNNN>
, aunque es casi completamente inútil, todavía proporciona tipo, id()
(para distinguir diferentes objetos) e indica que no hay mejor representación disponible.
>>> 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)
El resultado es una cadena que el intérprete de Python puede analizar y da como resultado un objeto igual.
Si eso no es posible, debería devolver una cadena en forma de <...some useful description...>
.