Python object.__repr__(self) should be an expression?

Python

Python Problem Overview


I was looking at the builtin object methods in the Python documentation, and I was interested in the documentation for object.__repr__(self). Here's what it says:

> Called by the repr() built-in function > and by string conversions (reverse > quotes) to compute the “official” > string representation of an object. If > at all possible, this should look like > a valid Python expression that could > be used to recreate an object with the > same value (given an appropriate > environment). If this is not possible, > a string of the form <...some useful > description...> should be returned. > The return value must be a string > object. If a class defines repr() > but not str(), then repr() is > also used when an “informal” string > representation of instances of that > class is required. > > This is typically used for debugging, > so it is important that the > representation is information-rich and > unambiguous

The most interesting part to me, was...

> If at all possible, this should look like a valid Python expression that could be used to recreate an object with the same value

... but I'm not sure exactly what this means. It says it should look like an expression which can be used to recreate the object, but does that mean it should just be an example of the sort of expression you could use, or should it be an actual expression, that can be executed (eval etc..) to recreate the object? Or... should it be just a rehasing of the actual expression which was used, for pure information purposes?

In general I'm a bit confused as to exactly what I should be putting here.

Python Solutions


Solution 1 - Python

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

The output is a string that can be parsed by the python interpreter and results in an equal object.

If that's not possible, it should return a string in the form of <...some useful description...>.

Solution 2 - Python

It should be a Python expression that, when eval'd, creates an object with the exact same properties as this one. For example, if you have a Fraction class that contains two integers, a numerator and denominator, your __repr__() method would look like this:

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

Assuming that the constructor takes those two values.

Solution 3 - Python

Guideline: If you can succinctly provide an exact representation, format it as a Python expression (which implies that it can be both eval'd and copied directly into source code, in the right context). If providing an inexact representation, use <...> format.

There are many possible representations for any value, but the one that's most interesting for Python programmers is an expression that recreates the value. Remember that those who understand Python are the target audience—and that's also why inexact representations should include relevant context. Even the default <XXX object at 0xNNN>, while almost entirely useless, still provides type, id() (to distinguish different objects), and indication that no better representation is available.

Solution 4 - Python

"but does that mean it should just be an example of the sort of expression you could use, or should it be an actual expression, that can be executed (eval etc..) to recreate the object? Or... should it be just a rehasing of the actual expression which was used, for pure information purposes?"

Wow, that's a lot of hand-wringing.

  1. An "an example of the sort of expression you could use" would not be a representation of a specific object. That can't be useful or meaningful.

  2. What is the difference between "an actual expression, that can ... recreate the object" and "a rehasing of the actual expression which was used [to create the object]"? Both are an expression that creates the object. There's no practical distinction between these. A repr call could produce either a new expression or the original expression. In many cases, they're the same.

Note that this isn't always possible, practical or desirable.

In some cases, you'll notice that repr() presents a string which is clearly not an expression of any kind. The default repr() for any class you define isn't useful as an expression.

In some cases, you might have mutual (or circular) references between objects. The repr() of that tangled hierarchy can't make sense.

In many cases, an object is built incrementally via a parser. For example, from XML or JSON or something. What would the repr be? The original XML or JSON? Clearly not, since they're not Python. It could be some Python expression that generated the XML. However, for a gigantic XML document, it might not be possible to write a single Python expression that was the functional equivalent of parsing XML.

Solution 5 - Python

'repr' means representation. First, we create an instance of class coordinate.

x = Coordinate(3, 4) 

Then if we input x into console, the output is

<__main__.Coordinate at 0x7fcd40ab27b8>

If you use repr():

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

the output is as same as 'Coordinate(3, 4)', except it is a string. You can use it to recreate a instance of coordinate.

In conclusion, repr() method is print out a string, which is the representation of the object.

Solution 6 - Python

To see how the repr works within a class, run the following code, first with and then without the repr method.

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)

Solution 7 - Python

I think the confusion over here roots from the english. I mean __repr__(); short for 'representation' of the value I'm guessing, like @S.Lott said

>"What is the difference between "an actual expression, that can ... recreate the object" and "a rehasing of the actual expression which was used [to create the object]"? Both are an expression that creates the object. There's no practical distinction between these. A repr call could produce either a new expression or the original expression. In many cases, they're the same."

But in some cases they might be different. E.g; coordinate points, you might want c.coordinate to return: 3,5 but c.__repr__ to return Coordinate(3, 5). Hope that makes more sense...

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAlex McBrideView Question on Stackoverflow
Solution 1 - PythonGeorg SchöllyView Answer on Stackoverflow
Solution 2 - PythonPaige RutenView Answer on Stackoverflow
Solution 3 - PythonRoger PateView Answer on Stackoverflow
Solution 4 - PythonS.LottView Answer on Stackoverflow
Solution 5 - PythonmarkchernView Answer on Stackoverflow
Solution 6 - PythonSaeed AhmedView Answer on Stackoverflow
Solution 7 - Pythonsle7enView Answer on Stackoverflow