6

I am trying to learn python with my own and i stucked at __repr__ function. Though i have read lots of post on __repr__ along with the python document. so i have decided to ask this Question here. The code bellow explains my confusion.

class Point:

    def __init__(self,x,y):
            self.x, self.y = x,y

    def __repr__(self):
        return 'Point(x=%s, y=%s)'%(self.x, self.y)

    def print_class(self):
        return 'Point(x=%s, y=%s)'%(self.x, self.y)



p = Point(1,2)

print p
print p.print_class()


Point(x=1, y=2)
Point(x=1, y=2)

If a normal function can also perform similar task then what is the extra advantage of __repr__ over print_class() (in my case a normal function) function.

Matteo Italia
  • 123,740
  • 17
  • 206
  • 299
jax
  • 3,927
  • 7
  • 41
  • 70

3 Answers3

5

The __repr__ function is called by repr() internally. repr() is called when you are printing the object directly , and the class does not define a __str__() . From documentation -

object.__repr__(self)

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.

In your case for print_class() , you have to specifically call the method when printing the object. But in case of __repr__() , it gets internally called by print .

This is especially useful, when you are mixing different classes/types . For Example lets take a list which can have numbers and objects of your point class, now you want to print the elements of the list.

If you do not define the __repr__() or __str__() , you would have to first check the instance , whether its of type Point if so call print_class() , or if not directly print the number.

But when your class defines the __repr__() or __str__() , you can just directly call print on all the elements of the list, print statement would internally take care of printing the correct values.

Example , Lets assume a class which has print_class() method, but no __repr__() or __str__() , code -

>>> class CA:
...     def __init__(self,x):
...             self.x = x
...     def print_class(self):
...             return self.x
...
>>> l = [1,2,3,CA(4),CA(5)]
>>> for i in l:
...     print(i)
...
1
2
3
<__main__.CA object at 0x00590F10>
<__main__.CA object at 0x005A5070>
SyntaxError: invalid syntax
>>> for i in l:
...     if isinstance(i, CA):
...             print(i.print_class())
...     else:
...             print(i)
...
1
2
3
4
5

As you can see, when we mix numbers and objects of type CA in the list, and then when we just did print(i) , it did not print what we wanted. For this to work correctly, we had to check the type of i and call the appropriate method (as done in second case).

Now lets assume a class that implements __repr__() instead of print_class() -

>>> class CA:
...     def __init__(self,x):
...             self.x = x
...     def __repr__(self):
...             return str(self.x)
...
>>>
>>> l = [1,2,3,CA(4),CA(5)]
>>> for i in l:
...     print(i)
...
1
2
3
4
5

As you can see in second case, simply printing worked, since print internally calls __str__() first, and as that did not exist fell back to __repr__() .

And not just this, when we do str(list) , internally each list's element's __repr__() is called. Example -

First case (without __repr__() ) -

>>> str(l)
'[1, 2, 3, <__main__.CA object at 0x005AB3D0>, <__main__.CA object at 0x005AB410>]'

Second case (with __repr__() ) -

>>> str(l)
'[1, 2, 3, 4, 5]'

Also, in interactive interpreter, when you are directly using the object, it shows you the output of repr() function, Example -

>>> class CA:
...     def __repr__(self):
...             return "CA instance"
...
>>>
>>> c = CA()
>>> c
CA instance
Sharon Dwilif K
  • 1,218
  • 9
  • 17
Anand S Kumar
  • 88,551
  • 18
  • 188
  • 176
3

The difference is that the __repr__ function is automatically called by Python in certain contexts, and is part of a predefined API with specific requirements. For instance, if you enter p by itself(not print p) in the interactive shell after creating your p object, its __repr__ will be called. It will also be used for print p if you don't define a __str__on p. (That is, you had to write print p.print_class(), but you didn't have to write print p.__repr__(); Python called __repr__ automatically for you.) The requirements for __repr__ are described in the documentation:

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.

In short, if you write your own method called print_class you can make it do whatever you want and tell people how to use it, because it's your API. If you use __repr__ you're supposed to follow the conventions of Python's API. Either one may make sense depending on the context.

BrenBarn
  • 242,874
  • 37
  • 412
  • 384
0

It helps you do more efficient coding work. even though you get same result using user define method like 'print_class()' as repr, but you don't need to type in '.print_class()' by repr method.

lazyjin
  • 11
  • 4