When you define a custom class in Python and print its instance using the print() function, by default, internal information (memory address) like <__main__.ClassName object at 0x...> is displayed, which is hard for humans to understand. To display the contents of an object (like attribute values) in an easy-to-understand way during debugging or logging, you need to define the special methods __str__ and __repr__.
This article explains the differences in roles between these two methods and how to implement them.
Default Behavior (When Methods are Undefined)
First, let’s check the behavior when these methods are not defined. As an example, we create a Book class to manage book data.
class Book:
def __init__(self, title, author, price):
self.title = title
self.author = author
self.price = price
# Instantiation
my_book = Book("Intro to Python", "Taro Yamada", 2800)
# Output with print()
print(f"print output: {my_book}")
Output:
print output: <__main__.Book object at 0x000001A2B3C4D5E6>
As you can see, only the object type and memory address are displayed, making it impossible to tell which book it is.
1. __str__ Method: Representation for Users
The __str__ method is used to define a “readable string representation for users” of the object. It is mainly called in the following situations:
- Passed to the
print()function - Converted to a string using the
str()function - Embedded in a string using f-strings or the
format()method
class Book:
def __init__(self, title, author, price):
self.title = title
self.author = author
self.price = price
def __str__(self):
# Return a format easy for users to read (e.g., Title and Author)
return f"『{self.title}』 Author:{self.author} ({self.price} yen)"
my_book = Book("Intro to Python", "Taro Yamada", 2800)
print(f"__str__ output: {my_book}")
Output:
Plaintext
__str__ output: 『Intro to Python』 Author:Taro Yamada (2800 yen)
The result of print() has changed to a format that is easy for humans to understand.
2. __repr__ Method: Representation for Developers
The __repr__ method is used to define a “strict and unambiguous string representation for developers” of the object. Ideally, it is recommended to return a format (string representation as code) that can restore the original object if executed with the eval() function.
It is mainly called in the following situations:
- Passed to the
repr()function - Typing the variable name and pressing Enter in the interactive shell
- When a list or dictionary containing objects is displayed
- As a backup when
__str__is not defined
class Book:
def __init__(self, title, author, price):
self.title = title
self.author = author
self.price = price
def __repr__(self):
# For developers: Return a format that can recreate the object
return f"Book(title='{self.title}', author='{self.author}', price={self.price})"
my_book = Book("Intro to Python", "Taro Yamada", 2800)
# Call using the repr() function
print(f"__repr__ output: {repr(my_book)}")
Output:
__repr__ output: Book(title='Intro to Python', author='Taro Yamada', price=2800)
Using __str__ and __repr__ Together
Let’s check the behavior when both methods are defined and how they are displayed inside a list.
class Book:
def __init__(self, title, author, price):
self.title = title
self.author = author
self.price = price
def __str__(self):
return f"Book: {self.title}"
def __repr__(self):
return f"Book('{self.title}', '{self.author}', {self.price})"
book1 = Book("Future of AI", "Jiro Sato", 3500)
book2 = Book("Basics of Statistics", "Hanako Suzuki", 2200)
print("1. print(book1) (__str__ takes precedence):")
print(book1)
print("\n2. print(repr(book1)) (Specify __repr__):")
print(repr(book1))
print("\n3. Inside a list (Elements in a list are displayed using __repr__):")
book_list = [book1, book2]
print(book_list)
Output:
1. print(book1) (__str__ takes precedence):
Book: Future of AI
2. print(repr(book1)) (Specify __repr__):
Book('Future of AI', 'Jiro Sato', 3500)
3. Inside a list (Elements in a list are displayed using __repr__):
[Book('Future of AI', 'Jiro Sato', 3500), Book('Basics of Statistics', 'Hanako Suzuki', 2200)]
Important Point: When you store objects in a collection like a list or dictionary and print it, the element objects are displayed using __repr__, not __str__. This is to accurately grasp the contents during debugging.
Summary
__str__: For end-users. A readable string displayed byprint().__repr__: For developers (debugging). A strict string displayed byrepr(). Also used when displaying list contents.
As an implementation guideline, defining at least __repr__ is recommended first, as it functions as a substitute when __str__ is missing.
