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?
# 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:
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.
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.
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.
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:
Top comments (2)
This is really cool! I never knew what repr was, so this helped me a lot. Thanks!
Just so you know,
__
in markdown means bold, so instead of seeing__repr__()
, I see repr().Edit: To show the
__
, just add backticks (`).I wrote a similar article Embrace the power of
__repr__
just a few days ago ;-)