str vs repr in Python: Explained
Published on
In the realm of Python programming, __str__
and __repr__
are dunder (double underscore) methods, also known as magic methods or special methods. They serve as the backbone for object-oriented programming in Python. This comprehensive guide seeks to illuminate the distinctive functionalities of these two methods, their significance in Python, and the appropriate instances for their application. Additionally, this guide will present numerous code examples to cement the underlying concepts.
Want to quickly create Data Visualization from Python Pandas Dataframe with No code?
PyGWalker is a Python library for Exploratory Data Analysis with Visualization. PyGWalker (opens in a new tab) can simplify your Jupyter Notebook data analysis and data visualization workflow, by turning your pandas dataframe (and polars dataframe) into a Tableau-style User Interface for visual exploration.
Defining the Terms: __str__
vs __repr__
Before diving into the deep end, let's start by defining these two important methods:
__str__
Method
In Python, __str__
is the method used to compute the "informal" or nicely printable string representation of an object. It is aimed at providing a human-readable output. Thus, readability is a key consideration when implementing this method.
Here's a simple example:
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return f'{self.name} is {self.age} years old.'
john = Person('John Doe', 30)
print(str(john)) # Outputs: John Doe is 30 years old.
__repr__
Method
On the other hand, __repr__
is a method used to compute the "official" string representation of an object. Its purpose is to provide a detailed representation that could be used to recreate the object if fed to the eval()
function. It's particularly useful for debugging and logging, since it provides a comprehensive description of the object.
Consider the same Person
class, but with a __repr__
method:
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __repr__(self):
return f'Person(name={self.name}, age={self.age})'
john = Person('John Doe', 30)
print(repr(john)) # Outputs: Person(name=John Doe, age=30)
When to Use __str__
vs __repr__
Now that we have a basic understanding of these methods, let's explore when to use each one.
Implementing __str__
for User-friendly String Representation
The __str__
method is primarily aimed at end users. It provides an informal, more readable description of an object. You can think of it as a way of displaying objects in a way that makes sense to users who are not necessarily programmers.
When implementing this method in your Python classes, focus on delivering information that is most relevant and beneficial to the end-user.
class Product:
def __init__(self, name, price):
self.name = name
self.price = price
def __str__(self):
return f'{self.name} costs ${self.price}.'
iPhone = Product('iPhone', 999)
print(str(iPhone)) # Outputs: iPhone costs $999.
In the above example, the __str__
method provides a simple, human-readable description of the Product
object. The output from str(iPhone)
could be displayed directly to users on a website or in an app.
Implementing __repr__
for Debugging and Development
The __repr__
method, conversely, is primarily intended for developers. It provides a complete and unambiguous representation of the object, which can be very useful for debugging and logging.
A golden rule when implementing the __repr__
method is that it should, if feasible, return a string that allows the recreation of the object using the eval()
function. This isn't always achievable, especially for complex objects, but it's a good guideline to follow.
Consider the Product
class with a __repr__
method:
class Product:
def __init__(self, name, price):
self.name = name
self.price = price
def __repr__(self):
return f'Product(name={self.name}, price={self.price})'
iPhone = Product('iPhone', 999)
print(repr(iPhone)) # Outputs: Product(name=iPhone, price=999)
The __repr__
method's output is much more detailed and technical compared to the __str__
method. This level of detail is exactly what a developer needs for effective debugging or logging.
Tailoring __str__
and __repr__
for Your Python Classes
Now that you understand the primary use-cases for both methods, let's discuss how to tailor them to your needs. In many cases, you'll want to define both methods in your classes, but their implementation will depend heavily on your specific use-case.
Establishing __str__
for Custom Informal String Representation
When defining the __str__
method, think about the people who will be interacting with your object and what they need to know. The method should return a string that gives a concise, human-readable summary of the object.
Suppose we have a Movie
class in a cinema ticket booking application:
class Movie:
def __init__(self, title, director, rating):
self.title = title
self.director = director
self.rating = rating
def __str__(self):
return f'{self.title} by {self.director}, rated {self.rating}/10.'
inception = Movie('Inception', 'Christopher Nolan', 8.8)
print(str(inception)) # Outputs: Inception by Christopher Nolan, rated 8.8/10.
Crafting __repr__
for Detailed Object Description
When implementing the __repr__
method, consider what would be useful for someone debugging the code or logging the state of an object. The string should include all of the information necessary to understand the object at a glance.
Continuing with the Movie
class, a __repr__
method could look like this:
class Movie:
def __init__(self, title, director, rating):
self.title = title
self.director = director
self.rating = rating
def __repr__(self):
return f'Movie(title={self.title}, director={self.director}, rating={self.rating})'
inception = Movie('Inception', 'Christopher Nolan', 8.8)
print(repr(inception)) # Outputs: Movie(title=Inception, director=Christopher Nolan, rating=8.8)
FAQs: Understanding Python's __str__
and __repr__
We've now explored the core concepts of Python's __str__
and __repr__
methods. However, you may still have questions about these dunder methods. Let's address some frequently asked questions.
-
What happens if I don't define
__str__
and__repr__
in my Python class?If you don't define
__str__
or__repr__
in your class, Python uses its default implementations. The default__str__
method returns a string containing the class name and its address in memory, while the default__repr__
does the same. -
Should I always implement both
__str__
and__repr__
methods in my classes?It's good practice to implement at least
__repr__
, as it's used as a fallback if__str__
isn't defined. However, whether you implement both depends on your specific needs. If your class objects need to have a user-friendly string representation, then it's worth implementing__str__
as well. -
Can
__str__
and__repr__
return any type of string?While
__str__
and__repr__
can technically return any string, it's best to follow the conventions:__str__
should be readable and concise, while__repr__
should be detailed and, if possible, allow the object to be reproduced usingeval()
.