0

I've been learning Python rapidly and am getting confused with the representational form and string form of an object as well as the repr method. I call x = Point(1, 3) with the following code and get:

class Point():
def __init__(self, x, y):
    '''Initilizae the object'''
    self.x = x
    self.y = y
def __repr__(self):
    return "Point({0.x!r}, {0.y!r})".format(self)
def distance_from_origin(self):
    return math.hypot(self.x, self.y)
>>>x
Point(1, 3)

If !r conversion field is for representing the variable in a string that can be evaluated by Python to create another identical object using eval() statement, why doesn't this work:

class Point():
    def __init__(self, x, y):
        '''Initilizae the object'''
        self.x = x
        self.y = y
    def __repr__(self):
        return "{!r}".format(self)
    def distance_from_origin(self):
        return math.hypot(self.x, self.y)
>>>x
File "C:\...\...\examplepoint.py, line 8, in __repr__
   return "{!r}".format(self)
File "C:\...\...\examplepoint.py, line 8, in __repr__
   return "{!r}".format(self)
File "C:\...\...\examplepoint.py, line 8, in __repr__
   return "{!r}".format(self)
File "C:\...\...\examplepoint.py, line 8, in __repr__
   return "{!r}".format(self)
The same error for 100 more lines
RuntimeError: maximum recursion depth exceeded

I thought that the !r specification would create object x type Point into a string in representation form that would look like: Point(1, 3) or similar to the first run. How exactly does Python do this representation !r in string format and what exactly does it mean? Why doesn't the second example work?

q.Then
  • 2,743
  • 1
  • 21
  • 31
  • This is answered here: [Python string format : When to use !s conversion flag](http://stackoverflow.com/questions/25441628/python-string-format-when-to-use-s-conversion-flag). "Two conversion flags are currently supported: '!s' which calls str() on the value, and '!r' which calls repr()." – Lack Jan 23 '15 at 05:11

1 Answers1

3

!r calls repr() (which calls __repr__ internally) on the object to get a string. It makes no sense to ask for the representation of an object in the definition of its __repr__. That's recursive, which is what the traceback tells you. There is no requirement that the representation of the object has to to be evaluable, and Python does not create this sort of representation for you.

davidism
  • 121,510
  • 29
  • 395
  • 339