What is __repr__ in Python and how does it compare with __str__?
Tags: python, beginners, tutorial
Published: 2023-11-17 03:06:30


![programming](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ldkwacaac77auws1bl5d.jpg)

---
Learning a new programming language can feel overwhelming especially with the flood of information being thrown at you, similar to navigating a busy road with cars speeding past you. 

On my journey of exploration in python, I came about this curious code that I want to learn and understand more about. What is the `__repr__()` method and why is it necessary when defining class objects. How is it useful?  How is it different from `__str__()`?

Based on the official python docs, repr() will "return a string containing a printable representation of an object. 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(); otherwise, the representation is a string enclosed in angle brackets that contains the name of the type of the object together with additional information often including the name and address of the object. A class can control what this function returns for its instances by defining a `__repr__()` method."

On the other hand, as per the official python docs, str() is a "class construction for the buildin class str. str() acts similar to repr(). str() will return a string version of object. If object is not provided, returns the empty string."

Wait, to add on to the confusion. What does the double underscore mean and why is it important? Is `__repr__()` the same as repr()? Why am I using the definition of repr() instead of `__repr__()`? 

The double underscore before and after indicate that the method is a magic method (also called dunder method). These special methods are intended to be triggered by different cues and operators that interact with their objects, rather than being directly called by developers.

repr() acts as the trigger for __repr__(), essentially meaning that calling repr() will invoke __repr__(). This creates the impression that they are identical functions, both yielding the same result.

Ok, now that we have a basic understanding. Let's compare `__repr__()` and `__str__()`. Both return a string that will describe the object. The difference is in the way the object is described. Based on convention, `__repr__()` provides a more detailed description of the object mostly used by programmers to maintain and debug the code. Usually the return string can even be used to re-create the object equal to the original one. On the other hand, the `__str__()` method provides a more casual and simplified description of the object, typically tailored for the user. 

---

One of the first built-in functions you learn with Python is the print function. As the name implies, the print function prints the message on the screen once called. The message could be a string or any other object. In the background, the object is converted into a string through its `__str__()` method before being displayed on the screen. However, if the object's class lacks a defined `__str__()`, the `__repr__()` method is invoked as a fallback. But what if both `__str__()` and `__repr__()` are not defined?

```python
# print a simple string
print("Hello World")
>> Hello World

#print a object instance 
class Message:
  def __init__(self, message):
    self.message = message

greeting = Message("Hello World")
print(greeting)
>> <__main__.Message object at 0x7fc4849b3700>
```

Instead of printing the message `Hello World` like in the first example, we get the object defined with its Class name and its location in memory `<__main__.Message object at 0x7fc4849b3700>` which is in an unreadable, not useful format. Because there are no defined `__str__()` or `__repr__()` methods for the Message class, the default string representation is printed instead. This format is inherited from the object class which is the fundamental class for all Python classes. 
 
Now that we got this unreadable output, is there a way to make it usable? The most common workaround would be to print the class attributes itself, for example:

```python
print(greeting.message)
>> Hello World
```
There is a more elegant and interesting way by using the `__str__()` method while defining the class. When the `__str__()` method is defined within the class, it will override the build-in str method. 

```python
class Message:
  def __init__(self, message):
    self.message = message

  def __str__(self):
    return f'This is the message: {self.message}'

greeting = Message("Hello World")
print(greeting)
>> This is the message: Hello World
```
Great. So every time we use the print function, we are able to print out a readable formatted string instead.

If we are able to manipulate the message that is printed using `__str__()` then why is `__repr__()` necessary? However when you use a python REPL terminal and just inspect the greeting itself, it will return the same unreadable object from before.

![repl example](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8adcj1zoho4igtezmbq0.png)

This is where repr() becomes particularly useful. As mentioned on  the python docs, repr() will "return a string that would yield an object with the same value when passed to eval()".  So we will need to define `__repr__()` in our class definition in a way that it will produce the same object. Let us see this in action.

![repl2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x3abkvi9i1rkkl5l5ub2.jpg)

When we inspect the greeting, the return output is `Message(message ='Hello World')`. Where have we seen this output format before? The first `Message` is the class name followed by the parentheses and the attribute `message` needed to create an instance/object. With this representational string we are able to re-create an object equal to the original one. 

I hope this article has helped you understand the basic difference between repr(), str() and their corresponding dunder methods. Please feel free to comment or leave any feedback or corrections I need to address. 

Below are my sources:
- https://medium.com/swlh/understanding-repr-and-str-in-python-65dd41538943
- https://realpython.com/python-repr-vs-str/
- https://www.youtube.com/watch?v=aIdzBGzaxUo