Class Instances in Python. String Representations of Class... | by Sadrach Pierre, Ph.D. | Towards Data Science

Customizing how class instances are represented is a good way to simplify debugging and instance output. In this post, we will discuss how defining ‘__repr__’ and ‘__str__’ methods allows us to change the string representation of an instance.
Let’s get started!
To begin, let’s define a class that describes a YouTube channel. The class will contain attributes (data) specific to Youtube channels such as channel name, subscribers, and verification status :
class YouTube:    def __init__(self, channel_name, subscribers, verification):        self.channel_name = channel_name        self.subscribers = subscribers        self.verification = verification
Let’s create an instance of our YouTube class. As a reminder, an instance is a concrete occurrence of a class object. For our instance, let’s set attributes corresponding to one of my favorite YouTube channels, sentdex:
sentdex = YouTube('Sentdex', 847000, True)
Now that we’ve created our instance, let’s print out the instance:
print(sentdex)
We see that we have an object of type ‘YouTube’ at the specified memory address. While this corresponds to what we’d expect, it isn’t the most readable representation of our instance. If we’d like to change how this object is represented, we can define ‘__repr__’ and ‘__str__’ methods. First, let’s define the ‘__repr__’ method:
class YouTube:    def __init__(self, channel_name, subscribers, verification):        self.channel_name = channel_name        self.subscribers = subscribers        self.verification = verification            def __repr__(self):        return 'YouTube({0.channel_name!r}, {0.subscribers!r}, {0.verification!r})'.format(self)
Let’s redefine our object, ‘sentdex’, and print the result:
sentdex = YouTube('Sentdex', 847000, True)print(sentdex)
We see that the ‘__repr__’ method returns the code representation of our instance. It simply corresponds to the code we typed to create the instance.
Now, let’s define the ‘__str__’ method:
class YouTube:    def __init__(self, channel_name, subscribers, verification):        self.channel_name = channel_name        self.subscribers = subscribers        self.verification = verification            def __repr__(self):        return 'YouTube({0.channel_name!r}, {0.subscribers!r}, {0.verification!r})'.format(self)    def __str__(self):        return '({0.channel_name!s}, {0.subscribers!s}, {0.verification!s})'.format(self)
Let’s define our instance again and print the result:
sentdex = YouTube('Sentdex', 847000, True)print(sentdex)
We see that we now have a string representation of our instance. If we’d like to print out the code representation, with our current class implementation, we can use the built-in ‘repr()’ method:
sentdex = YouTube('Sentdex', 847000, True)print(repr(sentdex))
I’d also like to point out the difference in text formatting between ‘__repr__()’ and ‘__str__()’. The special ‘!r’ formatting code indicates the output of ‘__repr__()’ should be used instead of the default ‘__str__()’. For example, if we include ‘!r’ in our string:
sentdex = YouTube('Sentdex', 847000, True)print('sentdex is {0!r}'.format(sentdex))
We get the code representation. If we leave out the ‘!r’ code, the string representation is used as default:
sentdex = YouTube('Sentdex', 847000, True)print('sentdex is {0}'.format(sentdex))
Defining the ‘__repr__()’ and ‘__str__()’ methods is often good practice as it can make class instances much easier to interpret and debug downstream. For example, logging custom string representations of instances can provide programmers with much more useful information about the instance contents. I’ll stop here but I encourage you to play around with the code yourself. If you’re interested in learning more programming patterns related to class definitions in python, I encourage you to check out The Python Cookbook.
To summarize, in this post we discussed string representations of class instances. We showed how to define ‘__repr__()’ and ‘__str__()’ methods, which allowed us to display code representations and string representations of instances. This practice can make class instance contents transparent and can significantly simplify debugging when done well. I hope you found this post useful/interesting. The code in this post is available on GitHub. Thank you for reading!