repr is for developers and should be unambiguous; str is for users
The convention is that repr produces an unambiguous, ideally evaluable representation aimed at developers, while str produces a readable, human-facing string. If str is not defined, Python falls back to repr. The interactive prompt, containers, and logging with %r use repr; print() and str() use str. A good repr looks like a constructor call and includes the essential state. For containers, the elements are shown with repr, which is why implementing repr properly makes debugging much easier.
Follow the principle: eval(repr(obj)) == obj whenever it is practical and safe.
Never put sensitive data such as passwords or tokens in repr, because repr shows up in logs and exception tracebacks.
Trade-off: a faithful repr with all fields can be verbose; truncate long collections or large blobs deliberately.
Common mistake: implementing str only and wondering why lists and dicts show an unhelpful object address.
Common mistake: making repr raise, which can break debugging, logging, and error reporting.
Version note: the fallback from str to repr has always existed. f-strings and format() use format, which defaults to str.
0-2 years experience
2-5 years experience
5-8 years experience
8+ years experience