__repr__ vs __str__, and why every class should define __repr__
repr() is the unambiguous, developer-facing representation (ideally eval-able); str() is the
human-facing one. str() falls back to __repr__ if __str__ isn't defined, but the reverse is never
true. The detail that trips people up: containers (list, dict, ...) always use each element's
__repr__ when printed -- even if the element defines a nicer __str__ -- because a container's own
__str__/__repr__ are the same and both call repr() on their contents for unambiguity.
class Point:
def __init__(self, x, y):
self.x, self.y = x, y
def __repr__(self):
return f"Point({self.x!r}, {self.y!r})"
p = Point(1, 2)
print("str(p) with no __str__ defined -> falls back to __repr__:", str(p))
print("a list of p uses __repr__ regardless:", [p])
class PointWithStr(Point):
def __str__(self):
return f"({self.x}, {self.y})"
p2 = PointWithStr(1, 2)
print("str(p2) now uses the custom __str__:", str(p2))
print("...but inside a list, STILL __repr__, not __str__:", [p2])