[Python] __str__ VS __repr__ in Python

str, repr, str, repr

Sometimes, you will need to implement __str__ or __repr__ methods for your class. Do you know what they do? Is there any difference between them? The answer to this question can be found by searching. If it happens to be the first time you have seen this question, you might as well take a look.

The print statement and str() built-in function uses __str__ to display the string representation of the object while the repr() built-in function uses __repr__ to display the object.

str, repr

Following are differences:

  • __repr__ is used to generate a formal representation. It may be considered as a method of serializing an object, and in principle, it may be able to deserialize back to an object. It is mainly used for debugging and development. It’s goal is to be unambiguous and str’s is to be readable.

__str__ is used to generate informal representations. Format or print will call it to generate a “friendly” display for the user. It is used for creating output for end user.

If you need to implement it yourself, generally implement __str__.

repr for Debug

Executing repr(obj) in Python can get the string representation of obj, and this operation is equivalent to calling obj.__repr__(). And this string means that may be able to deserialize back to obj itself. Look at the following code:

1
2
3
4
5
6
7
x = [1,2,3]
repr(x)
#>'[1, 2, 3]'
eval('[1, 2, 3]')
#> [1, 2, 3]
eval(repr(x)) == x
#> True

We see that’[1, 2, 3]’ (note that there is a space after the comma) is the string representation of the data [1,2,3], the original data can be obtained by deserializing with eval. So what if the variable is a custom class?

1
2
3
4
5
6
7
class MyClass:
def __init__(self, arg):
self.arg = arg

x = MyClass(10)
repr(x)
#>'<__main__.MyClass object at 0x10a40ef98>'

As you can see, repr(x) gives the type of object and the ID (memory address) of the object. But if we try to deserialize with eval(repr(x)), it will fail. So being able to deserialize is actually a convention, not a compulsion. We try to override the default implementation:

1
2
3
4
5
6
7
8
9
10
11
12
class MyClass:
def __init__(self, arg):
self.arg = arg

def __repr__(self):
return'MyClass({})'.format(self.arg)

x = MyClass(10)
repr(x)
#>'MyClass(10)'
eval(repr(x))
#> MyClass(10)

You can see that the coverage of __repr__ has an effect, and it can be deserialized normally.

The above few examples are all to illustrate what is the use of the string generated by repr.

repr does not force the generated string to be deserialized

The string generated by repr is generally used for debugging, so the generally generated string should contain as much information as possible, and the information should be as clear as possible (for example, the ID is used to distinguish two different objects in the default implementation).
Don’t use repr and eval for serialization/deserialization, use pickle or json.
str is used to display

str for Display

The obj.__str__() method will be called during print(obj) or '{}'.format(obj), generally to provide users with a “friendly” display, so __str__ does not return in principle like __repr__ Values ​​are agreed, and you can do whatever you want.

1
2
3
4
5
6
>>> from datetime import datetime
>>> now = datetime.now()
>>> print(str(now))
2017-04-22 15:41:33.012917
>>> print(repr(now))
datetime.datetime(2017, 4, 22, 15, 41, 33, 12917)

In addition, the default implementation of __str__ calls the __repr__ method directly. Therefore, if the __repr__ method is overridden, the result of __str__ will also change.

References

[1] str() vs repr() in Python - GeeksforGeeks - https://www.geeksforgeeks.org/str-vs-repr-in-python/

[2] str() vs repr() in Python? - https://www.tutorialspoint.com/str-vs-repr-in-python