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().
