Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

what is the significance of `__repr__` function over normal function [duplicate]

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.

like image 804
jax Avatar asked Aug 05 '15 05:08

jax


1 Answers

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
like image 165
Anand S Kumar Avatar answered Nov 14 '22 22:11

Anand S Kumar