__str__ vs __repr__

RoadmapsPython

Overview

Python uses two main dunder methods to convert objects to strings. `__str__` is for readable output, and `__repr__` is for unambiguous developer representations. By default, both print `<__main__.MyClass object at 0x...>`, but overriding them gives meaningful descriptions. Think of `__str__` as the 'display name' for a user and `__repr__` as the 'technical ID card' for a developer. When writing `__repr__`, a common trap is forgetting quotes around string attributes, making the output ambiguous. Always use the `!r` conversion flag in f-strings to include quotes automatically. class User: def __init__(self, name): self.name = name def __repr__(self): # The !r ensures name prints as 'Alice' instead of Alice return f'User(name={self.name!r})'

It solves the problem of opaque object representations. Clear string representations make logging, debugging, and user interfaces significantly easier by avoiding memory addresses in terminal output.

Where used: Logging configuration, Pydantic error messages, REPL debugging

Why learn this

Code walkthrough

class Config:
  def __init__(self, env):
    self.env = env
  def __repr__(self):
    return f'Config(env={self.env!r})'

c = Config('prod')
print(c)
print([c])

Focus: print([c])

Aha moment

class Task:
  def __init__(self, name):
    self.name = name
  def __str__(self):
    return self.name

t = Task('build')
print([t])

Prediction: What does this print?

Common guess: `['build']`

Collections like `list` always use `__repr__` to format their elements, even if you print the list using `str()`. Since `Task` lacks a `__repr__`, you get the default memory address.

Common mistakes

Glossary

unambiguous
Clear and exact, leaving no doubt about what something is or what it means. Example: `User(name='Alice', role='admin')`.
REPL
Read-Eval-Print Loop; an interactive programming environment where you can type commands and see the results immediately. Example: `repr(obj)`.

Recall questions

Understanding checks

What does this code output?

Box()

When `__str__` is not explicitly defined, Python falls back to calling the object's `__repr__` method.

Why is it important to implement `__repr__` for an object instead of only `__str__`?

Because collections like `list` and `dict` use `__repr__` to display their elements, even if you print them using `str()`.

If you only implement `__str__`, printing a `list` of your objects will still show unhelpful memory addresses.

What does this code output?

Node('A')

The `!r` flag calls `repr()` on the string `'A'`, adding the necessary quotes around it.

Practice tasks

Basic User Representation

Create a `User` class with `name` and `role` attributes. Implement `__repr__` to return a string like `User(name='Alice', role='admin')` and `__str__` to return `Alice (admin)`.

Challenge

Logging Context

Write an `APIRequest` class taking `method` and `url`. Implement `__repr__` so that logging a list of requests shows them clearly as `APIRequest(method='GET', url='/users')`. Do not implement `__str__`.

Continue learning

Previous: Everything is an object in Python

Previous: Defining functions and return values

Return to Python Roadmap