__str__ vs. __repr__

Every now and then, when I go back to writing Python code after a break, a question comes to mind:

What message should I put into the __str__ and the __repr__ functions?

When you search for the difference between them, you will find out that __str__ should be human readable and __repr__ should be unambiguous (as explained in this StackOverflow question). It's a great, detailed answer. But for some reason, it never really stuck with me. I'm not the smartest developer and sometimes to remember something, I need a very simple example. What I actually found helpful was written straight in the documentation of the repr() function:

For many types, this function makes an attempt to return a string that would yield an object with the same value when passed to eval()

An excellent example of what it means, is the datetime module:

>>> import datetime
>>> now = datetime.datetime.now()
>>> str(now)
'2019-01-21 19:26:40.820153'
>>> repr(now)
'datetime.datetime(2019, 1, 21, 19, 26, 40, 820153)'

As you can see, the repr function returns a string that can be used to create an object with the same properties as now (not the same as now, but with the same properties). You can verify it by using the following code:

>>> timestamp = datetime.datetime(2019, 1, 21, 19, 26, 40, 820153)
>>> now == timestamp
True
# But!
>>> id(now) == id(timestamp)
False

So how can you use it in your own classes? For instance, if you are writing a class Car that has the attributes color and brand and is initialized in the following way:

red_volvo = Car(brand='volvo', color='red')

then this is what the __repr__ function for the car should return:

>>> repr(red_volvo)
"Car(brand='volvo', color='red')"

It's not always possible to write the __repr__ function that can recreate a given object, but simply keeping in mind those examples with datetime and Car has helped me to remember the difference between the __repr__ and __str__.

I found out about this trick in "Python Tricks" book, by Dan Bader. If you haven't heard of it, it's a great source of intermediate-level pieces of knowledge about Python. I'm in no way associated with Dan, but his book was one of the most enjoyable Python technical reads I've had in a long time.

Similar posts

type() vs. isinstance()

What's the difference between type() and isinstance() methods, and which one is better for checking the type of an object?

Ask for Forgiveness or Look Before You Leap?

Is it faster to "ask for forgiveness" or "look before you leap" in Python? And when it's better to use one over the other?

Checking for True or False

How can we compare a variable to True or False, what's the difference between "is" and "==" operators, and what are truthy values?