What's the difference between `__str__` and `__repr__`?
Quick Answer
`__repr__` returns an unambiguous, developer-facing representation (ideally one that could recreate the object) and is used by the REPL, debuggers, and containers (`print([obj])` calls `repr`, not `str`). `__str__` returns a human-readable, user-facing string and is used by `print(obj)`/`str(obj)`. If `__str__` is not defined, Python falls back to `__repr__`.
Detailed Answer
Two different audiences
from datetime import date
d = date(2024, 1, 15)
str(d) # '2024-01-15' -- readable
repr(d) # 'datetime.date(2024, 1, 15)' -- unambiguous, evaluable
__str__ targets end users / logs — readable output. __repr__ targets
developers debugging — precise, ideally eval()-able output that makes it
unambiguous exactly what the object is.
Defining both on a custom class
class Point:
def __init__(self, x, y):
self.x, self.y = x, y
def __repr__(self):
return f"Point(x={self.x}, y={self.y})"
def __str__(self):
return f"({self.x}, {self.y})"
p = Point(1, 2)
print(p) # (1, 2) -- calls __str__
print(repr(p)) # Point(x=1, y=2) -- calls __repr__
print([p]) # [Point(x=1, y=2)] -- containers always use repr()
The fallback rule
If you only define __repr__, str(obj) falls back to calling __repr__
(since object.__str__ calls self.__repr__() by default). So a common
shortcut for simple classes is to define only __repr__ and skip
__str__ entirely, unless the two representations genuinely need to
differ.
Why containers always use repr
print([1, "a", p]) shows [1, 'a', Point(x=1, y=2)] — note the quotes
around 'a' and the repr form of p. Lists, dicts, and other containers
call repr() on their elements so that nested strings are visibly quoted
and distinguishable from the surrounding structure; using str() would
make ["a", "b"] print as [a, b], indistinguishable from bare identifiers.
Interview-ready summary: __repr__ is for developers/debugging
(unambiguous, ideally eval-able); __str__ is for end users (readable).
str() falls back to __repr__ if __str__ isn't defined, and containers
always render their elements with repr, never str.