__str__ & __repr__ Methods

by John | November 25, 2020

 

The __str__ and __repr__ methods in Python are used when we print a representation of an instance. Let's take a the popular datetime module and show this how the __repr__ and __str__ have been implemented.

We can use the repr and str  keywords to call these methods.

 

import datetime as dt

d = dt.datetime.now()

print("__repr__ called: ", repr(d))

print("__str__ called: " ,str(d))

 

__repr__ called:  datetime.datetime(2020, 11, 24, 20, 16, 26, 925541)
__str__ called:  2020-11-24 20:16:26.925541

 

Notice that the repr isn't as user-friendly as the __str__ method. This is by design and generally the __repr__ method will be not be a client facing method i.e. no one but the programmer should see it.

Often the __repr__ method will be formatted as ClassName(attribute1, attribute2 ,..... , attribute n).

 

Let's take an example of a Country class which takes a name and a population (in millions). 

 

class Country:
    def __init__(self, name, population):
        self.name = name
        self.population = population


usa = Country('USA', 300)

print(usa)
print(repr(usa))
print(str(usa))    

 

When we run the code above the output will look something similar to the following:

<__main__.Country object at 0x000001E5A2CA1DC8>
<__main__.Country object at 0x000001E5A2CA1DC8>
<__main__.Country object at 0x000001E5A2CA1DC8>

 

Clearly the output above isn't very informative. Let's implement a __repr__ method to print a more informative message to the console. 

 

class Country:
    def __init__(self, name, population):
        self.name = name
        self.population = population
        
    def __repr__(self):
        print("showing the __repr__")
        return f"Country(name={self.name},population={self.population})"
    
         
usa = Country('USA', 300)

print(usa)
print(repr(usa))
print(str(usa))    

 

Take a look at the output from the print statements in the code block above. Notice that when we call str on the instance it returns the __repr__ method we implemented.

 

showing the __repr__
Country(name=USA,population=300)
showing the __repr__
Country(name=USA,population=300)
showing the __repr__
Country(name=USA,population=300)

 

The reason that Python calls the __repr__ method is that initially it looks for __str__ and if it can't find it, it looks for a __repr__ and shows that instead if it exists. 

 

Let's implement an __str__ method also on the Country class. 

 

class Country:
    def __init__(self, name, population):
        self.name = name
        self.population = population
        
    def __repr__(self):
        print("showing the __repr__")
        return f"Country(name={self.name},population={self.population})"
    
    def __str__(self):
        print("showing the __str__")
        return self.name
    
         
usa = Country('USA', 300)

print(usa)
print(repr(usa))
print(str(usa))  

 

Notice when we call print(usa) Python decides to use the __str__ method. Naturally the other two behave as expected. 

 

showing the __str__
USA

showing the __repr__
Country(name=USA,population=300)

showing the __str__
USA

 

When both the __str__ and the __repr__ methods are defined in a class, Python will show each depending on the context. For example, if you simply type the the instance into the console, it will return the __repr__ method. 

 

usa

Out:
showing the __repr__

Country(name=USA,population=300)

 

A good way to remember which is which regarding these two methods, is that the __str__ is more likely to be used for the end user of the code to view, whereas the __repr__ is more likely to be used by the programmers. 

 

 

Summary

- If one of __repr__ or __str__ is implemented by not both we can still use the repr and str keywords and Python will show whichever one has been implemented

 

- If both methods are implemented, Python will show each depending on the context in which is it called.

 

- Rule of thumb: __repr__ for programmers and __str__ for end users. 

 

 


Join the discussion

Share this post with your friends!