repr()

The debug representation — unambiguous, quoted, and often eval-able. The str/repr split lets one object display two ways.

Built-in functionPython 1.0+Live demo
Common call
print(f"got x={x!r}")
Returns
always a str — with quotes for strings, brackets for containers, and unambiguous marker chars
Replaces
the older `xml.sax.saxutils.escape`-style hand escaping when you just want to SEE what a value is
Watch out
for user-defined classes, only __repr__ is usually defined; str() falls back to __repr__ but not the reverse
repr(xxAny value. Python calls __repr__() on it — every object has one, so repr never raises AttributeError on missing method.type: Any · required)
str

Demo

Live evaluation
Try:
Inputs
xstrany value
Output
repr('hello')
'\'hello\''

repr wraps strings in quotes and escapes special characters — a newline becomes "\n" in the output, a tab becomes "\t", and internal quotes get escaped or the outer quote choice switches. That is by design: the output should be a valid Python literal you could paste back into code. str() would show the raw value; repr() shows how to type the same value.

Parameters

NameTypeRequiredDescription
xAnyyesAny value. Python calls __repr__() on it — every object has one, so repr never raises AttributeError on missing method.

Return value

strThe "official" string representation of the object, produced by calling __repr__(). For built-in types this is typically a valid Python literal that would recreate the object when passed to eval(). Never falls back to __str__.

Common patterns

Debug output
The `!r` format spec calls repr — the idiomatic way to include diagnostic data.
logger.debug(f"received user={user!r} action={action!r}")
Custom __repr__ for your class
A good __repr__ is unambiguous and, ideally, eval-able.
class Point:
    def __repr__(self):
        return f"Point({self.x!r}, {self.y!r})"
See through "which quote" ambiguity
When a string could contain either kind of quote, repr picks and escapes.
print(repr("say "hi""))
# "say "hi""  or  'say "hi"'

Examples

1. String gets quotes
repr("hello")
Returns
"'hello'"
2. Newline shown
repr("a\nb")
Returns
"'a\\nb'" # backslash + n
3. Tab escaped
repr("a\tb")
Returns
"'a\\tb'"
4. Contains a quote
repr("don\'t")
Returns
'"don\'t"' # switches to double quotes
5. Integer
repr(42)
Returns
"42"
6. None
repr(None)
Returns
"None"
7. List
repr([1, 2])
Returns
"[1, 2]"
8. Empty is quoted
repr("")
Returns
"''"

Pitfalls

1. repr is NOT the same as str
str is for humans — clean, unambiguous only when it needs to be. repr is for debugging — unambiguous ALWAYS, including quoting strings and escaping newlines. Confusing them leads to logs that read like the string vanished or was truncated.
Log shows raw
log.info(f"got {value}")   # value is "5\t"
# logs: got 5<TAB>
invisible tab in output
Log with repr
log.info(f"got {value!r}")
got '5\t'
2. repr() is NOT always eval-able
For built-in scalar types and simple containers it usually is. For objects, class instances, and file handles it typically is not — the docstring says &quot;typically&quot;, and CPython honors that phrase.
Assumed round-trip
eval(repr(user))
NameError: name User is not defined # or worse
Never eval untrusted repr
# repr is for HUMANS to read, not for machines to parse
3. For your classes, define __repr__ FIRST
If __str__ is missing, Python falls back to __repr__. The reverse is not true — no __repr__ and you get the default `<Foo object at 0x...>` from object. Define __repr__ once for both purposes; add __str__ only when human display differs.
Missing repr
class Point: pass
repr(Point())
<__main__.Point object at 0x7f...>
Define repr
class Point:
    def __repr__(self):
        return f"Point(...)"
"Point(...)"
4. repr on a huge collection can be huge
repr walks nested structures. Logging repr() of a 10 MB dict prints 10 MB of text. Truncate first if the object could be large.
Log floods
log.debug(repr(giant_state))
10 MB log line
Truncate
log.debug(repr(giant_state)[:200] + "...")
bounded

When to use

Use it
  • Debug / diagnostic output — logs, error messages, assertions
  • f-string with !r spec for logging user-provided values
  • Round-trippable data output for simple built-in types
  • Defining __repr__ on your own classes
Reach for something else
  • User-facing text → str is the correct tool
  • JSON output → json.dumps
  • Parsing objects — never eval a repr from untrusted input
  • Very large collections — truncate first

Notes

Complexity
Depends on the object — usually O(size) of the resulting text
Return
str — always
CPython impl
Python/bltinmodule.c :: builtin_repr — calls Py_TYPE(x)->tp_repr
Memory
Allocates one string; for nested structures, may allocate substrings recursively
Thread-safe
Yes for immutable inputs; not safe if the underlying object mutates during __repr__

FAQ

str is for humans — clean, presentable, may lose information. repr is for debugging — unambiguous, includes quotes for strings and escapes for special characters. For simple built-in types they usually differ; for containers repr shows how you would type it, str is essentially the same as repr.

History

1.0
repr() has been a builtin since Python 1.0.
2.6
`!r` format spec added for f-strings via PEP 3101 (later inherited by f-strings in 3.6).