repr() vs str() in Python


The object class is the base class for all classes, has a number of dunder (short for double underscore) methods. They are often called magic methods. These methods are never called directly. Instead, a corresponding built-in function internally calls one of these magic methods. For instance built-in str() function invokes __str__() method and repr() function invokes __repr__() method.

Example: str() and __str__() method on int object
>>> x=100
>>> print(str(x))
100
>>> print(x.__str__())
100

The following invokes the repr() and __repr__() method:

Example: repr() and __repr__() method on int object
>>> x=100
>>> print(repr(x))
100
>>> print(x.__repr__())
100

Apparently, there seems to be no difference between behavior of the __str__() and __repr__(). However, if we take a string object, the difference will be evident.

Example: __repr__() vs __str__()
>>> x="Hello World"
>>> print(x.__str__())
Hello World
>>> print(x.__repr__())
'Hello World'

Output of __repr__() is in quotes whereas that of __str__() is not. The reason can be traced to official definitions of these functions, which says that __repr__() method and hence (repr() function) computes official string representation of an object. The str() function i.e. __str__() method returns an informal or printable string representation of concerned object, which is used by the print() and format() functions.

If you try to use an object of any user-defined class as an argument for the print() function, it uses the default __str__() method of object's class. It doesn't tell any meaningful info of the object other than its id.

Example: Print an Object
class myclass:
    def __init__(self):
        self.name="Raj"
        self.age=21

obj = myclass()
print(obj)
Output
<__main__.myclass object at 0x000001E06B3ADE08>

Whereas, we would like to obtain string representation showing values of object attributes. This can be done by overriding the __str__() method in the myclass, as shown below.

Example: Override __str__() Method
class myclass:
    def __init__(self):
        self.name="Raj"
        self.age=21
    def __str__(self):
        return "name : {} age : {}".format(self.name, self.age)

obj=myclass()
print(obj)
print(str(obj))
Output
name : Raj age : 21
name : Raj age : 21

Note that str() function has used __str__() method in the class. The __repr__() method can also be used for same purpose. However, the str() function by default uses __str__(), if not found uses __repr__().

Another difference between the two is, __str__() should always return a string, whereas the __repr__() can return any valid Python expression. Let us add both methods in myclass so that the __repr__() returns a dict object.

Example: Override __str__() and __repr__()
class myclass:
    def __init__(self):
        self.name="Raj"
        self.age=21
    def __str__(self):
        return "name : {} age : {}".format(self.name, self.age)
    def __repr__(self):
        return {"name":self.name, "age":self.age}
        

obj = myclass()
print(obj.__str__())
print(obj.__repr__())
Output
name : Raj age : 21
{'name': 'Raj', 'age': 21}

Now, this will bring out exact difference between the two. While str() correctly implements the __str__(), repr() function throws the TypeError as it needs __repr__() toreturn a string.

Example: repr() vs str()
print(str(obj))
print(repr(obj))
Output
name : Raj age : 21
TypeError: __repr__ returned non-string (type dict)

The output of __repr__() method is mostly machine-readable and is mainly used for debugging purposes. Hence it is desired to be furnishing unambiguous representation of the object.

Purpose of __str__() is to generate a printable string representation that is informal in nature and human-readable in nature.