Definition of __repr__ in Python
__repr__ is a special method (also called a dunder method or magic method) in Python that allows you to define the official representation of an object as a string. Its name comes from the word representation. When you call the built-in repr() function on an object or inspect an object directly in a Python interpreter, it is the __repr__ method that is invoked behind the scenes.
The main goal of __repr__ is to provide an unambiguous representation of the object, ideally precise enough for a developer to recreate the object from that string. If you want to deepen your knowledge of Python and master special methods, we recommend following our comprehensive Python course which covers object-oriented programming in detail.
The golden rule: __repr__ is intended for developers, while __str__ is intended for end users. If you can only implement one of the two methods, always choose __repr__.
How does __repr__ work?
Every object in Python inherits from the base class object, which provides a default implementation of __repr__. This default implementation returns a string containing the class name and the memory address of the object, which is generally not very useful:
class Car:
def __init__(self, brand, model):
self.brand = brand
self.model = model
my_car = Car("Toyota", "Corolla")
print(repr(my_car))
# Result: <__main__.Car object at 0x7f8b8c0d4a90>As you can see, this default output tells us nothing about the actual content of the object. That is why it is strongly recommended to define your own __repr__ method in your custom classes.
Custom implementation of __repr__
Here is how to properly implement __repr__ for our Car class:
class Car:
def __init__(self, brand, model, year):
self.brand = brand
self.model = model
self.year = year
def __repr__(self):
return f"Car(brand='{self.brand}', model='{self.model}', year={self.year})"
my_car = Car("Toyota", "Corolla", 2023)
print(repr(my_car))
# Result: Car(brand='Toyota', model='Corolla', year=2023)Notice that we use an f-string here to format the output. The idea is that the returned string should resemble the constructor call that would allow you to recreate the object.
Difference between __repr__ and __str__
The distinction between __repr__ and __str__ is a frequent source of confusion for developers. Here is a summary table to clearly understand their differences:
| Characteristic | __repr__ | __str__ |
|---|---|---|
| Target audience | Developers | End users |
| Goal | Unambiguous representation | Readable representation |
| Called by | repr(), interactive interpreter | str(), print() |
| Fallback | Default implementation from object | Uses __repr__ if not defined |
| Convention | Should look like valid Python code | Free format, focused on readability |
Important point: if you define __repr__ but not __str__, Python will automatically use __repr__ as a fallback when calling print or str(). The reverse is not true.
Here is a concrete example illustrating both methods:
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})"
def __str__(self):
return f"{self.name} - ${self.price}"
product = Product("Mechanical Keyboard", 89.99)
# __repr__ is called in the interpreter or via repr()
print(repr(product)) # Product(name='Mechanical Keyboard', price=89.99)
# __str__ is called by print() or str()
print(product) # Mechanical Keyboard - $89.99
When is __repr__ called?
The __repr__ method is invoked in several contexts that you should know about:
1. In the interactive interpreter
When you type the name of an object directly in the Python interpreter (or in a Jupyter notebook), it is __repr__ that is called:
>>> product = Product("Mouse", 49.99)
>>> product
Product(name='Mouse', price=49.99)
2. Inside containers (lists, dictionaries, etc.)
When an object is inside a container like a list or a dict, Python uses __repr__ to display it, even if you call print on the container:
products = [
Product("Keyboard", 89.99),
Product("Mouse", 49.99),
Product("Monitor", 299.99)
]
print(products)
# [Product(name='Keyboard', price=89.99), Product(name='Mouse', price=49.99), Product(name='Monitor', price=299.99)]This is an extremely important behavior to understand: even if your objects have a very readable __str__, it is __repr__ that will be used when they are inside a list or a dictionary.
3. With the repr() function
The built-in repr() function directly calls __repr__:
product = Product("Webcam", 59.99)
repr_str = repr(product)
print(repr_str) # Product(name='Webcam', price=59.99)
4. In f-strings with the !r flag
You can force the use of __repr__ in an f-string using the !r flag:
product = Product("Headset", 129.99)
print(f"Debug: {product!r}")
# Debug: Product(name='Headset', price=129.99)
print(f"Display: {product!s}")
# Display: Headset - $129.99
Advanced examples
__repr__ with inheritance
When working with class inheritance, it is important to define __repr__ correctly at each level of the hierarchy:
class Animal:
def __init__(self, name, species):
self.name = name
self.species = species
def __repr__(self):
return f"Animal(name='{self.name}', species='{self.species}')"
class Dog(Animal):
def __init__(self, name, breed):
super().__init__(name, species="Dog")
self.breed = breed
def __repr__(self):
return f"Dog(name='{self.name}', breed='{self.breed}')"
dog = Dog("Rex", "German Shepherd")
print(repr(dog)) # Dog(name='Rex', breed='German Shepherd')
__repr__ with dataclasses
dataclass in Python automatically generate a __repr__ method for you, which is one of their great advantages:
from dataclasses import dataclass
@dataclass
class Point:
x: float
y: float
z: float = 0.0
point = Point(1.5, 2.3, 4.0)
print(repr(point)) # Point(x=1.5, y=2.3, z=4.0)As you can see, the dataclass generates a __repr__ that perfectly follows conventions. You can however disable this behavior with @dataclass(repr=False) if you want to define your own implementation.
__repr__ with namedtuples
Similarly, namedtuple automatically provide an informative __repr__:
from collections import namedtuple
Color = namedtuple("Color", ["red", "green", "blue"])
c = Color(255, 128, 0)
print(repr(c)) # Color(red=255, green=128, blue=0)
__repr__ and eval()
One of the most important conventions of __repr__ is that, whenever possible, the returned string should be valid Python code that can recreate the object:
class Vector:
def __init__(self, x, y):
self.x = x
self.y = y
def __repr__(self):
return f"Vector({self.x}, {self.y})"
def __eq__(self, other):
return self.x == other.x and self.y == other.y
v1 = Vector(3, 4)
v2 = eval(repr(v1)) # Recreates the object from its repr
print(v1 == v2) # True
print(repr(v2)) # Vector(3, 4)Warning: never use eval() on untrusted data in production. This example is purely illustrative of the __repr__ convention.
Best practices
Here are the essential rules to follow when implementing __repr__ in your classes:
1. Always implement __repr__
Even if you define __str__, always implement __repr__. It is the most fundamental representation method and serves as a fallback for __str__.
2. Return valid Python code if possible
The convention is that __repr__ should return a string that, when passed to eval(), would recreate the object:
# Good practice
def __repr__(self):
return f"MyClass(param1={self.param1!r}, param2={self.param2!r})"
# Bad practice
def __repr__(self):
return f"Instance of MyClass"Note the use of !r in the f-string for string attributes. This ensures that quotes are included in the output, making the representation more accurate.
3. Use the <...> format when eval() is not possible
If your object is too complex to be recreated via eval(), use the angle bracket convention:
class DatabaseConnection:
def __init__(self, host, port, database):
self.host = host
self.port = port
self.database = database
self._connection = None # Complex internal state
def __repr__(self):
return f""
conn = DatabaseConnection("localhost", 5432, "my_app")
print(repr(conn)) #
4. Include essential information
The representation should contain enough information to identify the object and distinguish it from other instances. At a minimum, include the attributes defined in the constructor (__init__ via def).
5. Keep the representation concise
Avoid including internal attributes or implementation details that are not relevant for debugging:
# Too verbose
def __repr__(self):
return (f"User(id={self.id}, name='{self.name}', email='{self.email}', "
f"created_at={self.created_at}, last_login={self.last_login}, "
f"login_count={self.login_count}, preferences={self.preferences})")
# Just right
def __repr__(self):
return f"User(id={self.id}, name='{self.name}', email='{self.email}')"
__repr__ for Python built-in types
It is interesting to note that all built-in Python types already implement __repr__ consistently:
# Strings
print(repr("Hello")) # 'Hello'
# Numbers
print(repr(42)) # 42
print(repr(3.14)) # 3.14
# Lists
print(repr([1, 2, 3])) # [1, 2, 3]
# Tuples
print(repr((1, 2))) # (1, 2)
# Dictionaries
print(repr({"a": 1})) # {'a': 1}
# Sets
print(repr({1, 2, 3})) # {1, 2, 3}You will notice that for strings, repr() adds quotes around the value, which clearly distinguishes it from str(). This is particularly useful for debugging when working with tuple, set, or dict.
Frequently asked questions
What is the difference between __repr__ and __str__ in Python?
__repr__ provides a technical and unambiguous representation of the object, intended for developers. It should ideally return valid Python code that can recreate the object. __str__, on the other hand, provides a readable and user-friendly representation, intended for end users. If __str__ is not defined, Python uses __repr__ as a fallback. The convention recommends always defining __repr__ first.
Should I always implement __repr__ in my classes?
Yes, it is a strongly recommended best practice. Without a custom implementation, Python uses the default representation from object which only displays the class name and memory address, which is not useful for debugging. If you use dataclass or namedtuple, the __repr__ method is automatically generated, saving you from writing it manually.
Why is __repr__ used inside lists and dictionaries?
When Python displays the content of a container (list, dict, tuple, etc.), it uses __repr__ and not __str__ for each element. This design choice is explained by the fact that displaying a container is generally intended for debugging, and Python therefore favors the unambiguous representation. This is why it is essential to have an informative __repr__ to properly visualize your objects.
How can I learn to master special methods in Python?
Special methods like __repr__, __str__, __init__, or __eq__ are at the heart of object-oriented programming in Python. To master them in depth, we recommend following our dedicated Python course on Believemy, which progressively and practically covers all these essential concepts, from the basics to advanced topics.