The repr(object) built-in function returns a printable string containing an unambiguous, formal representation of an object.
Unambiguity & eval() Round-Tripping: While str() generates human-friendly informal text, repr() aims to produce an information-rich representation that, when possible, matches the valid Python expression needed to recreate the object via eval(). It invokes the object's __repr__() dunder method. To inspect object attributes dynamically, see vars() and type().
The repr() function accepts a single object and returns its formal string representation:
# Formal syntax of built-in repr()
canonical_string = repr(object)
| Parameter | Type Accepted | Behavioral Details |
|---|---|---|
object |
Any Python object | The target instance whose official representation is requested. |
| Return Value | str |
A string representation, ideally containing enough detail to reconstruct the object via eval(). |
Unlike str() which renders newlines and special characters visually, repr() keeps quotes and escapes control sequences explicitly:
# 1. Official representation of collections and strings
data_set = {5, 6, 2, 4}
repr_str = repr(data_set)
print("Original type: ", type(data_set))
print("repr() type: ", type(repr_str))
print("repr() output: ", repr_str)
# 2. String representation shows quotes and escape sequences
text = "Hello\nWorld"
print("str() display: ")
print(str(text))
print("repr() display:", repr(text))
Output:
Original type:
repr() type:
repr() output: {2, 4, 5, 6}
str() display:
Hello
World
repr() display: 'Hello\nWorld'
A canonical guideline in Python is that eval(repr(obj)) == obj should hold true for standard built-in data types:
# Round-trip reconstruction with eval(repr(obj)) == obj
sample_str = "Hi"
print("repr(sample_str):", repr(sample_str)) # 'Hi'
print("str(sample_str): ", str(sample_str)) # Hi
# eval(str(sample_str)) fails because Hi is interpreted as an undefined variable!
# eval(repr(sample_str)) succeeds because the quotes are preserved:
print("eval(repr(s)) == s:", eval(repr(sample_str)) == sample_str)
# Reconstructing complex collections
records = [{"id": 1, "valid": True}, {"id": 2, "valid": False}]
recreated = eval(repr(records))
print("Recreated equals original:", recreated == records)
Output:
repr(sample_str): 'Hi'
str(sample_str): Hi
eval(repr(s)) == s: True
Recreated equals original: True
Compare the behavioral and design differences between user-facing text and developer representation:
| Feature | str(obj) |
repr(obj) |
|---|---|---|
| Primary Goal | Human readability & UI display | Unambiguous technical precision |
| Quotes on Strings | Omits surrounding quotes | Includes quotes (e.g. 'hello') |
| Dunder Method | __str__() (falls back to __repr__()) |
__repr__() |
| Used By | print(), format(), f-strings |
Interactive REPL, debugger, logging |
import datetime
# Date and time objects: informal string vs unambiguous representation
fixed_dt = datetime.datetime(2026, 10, 15, 8, 30, 45, 123456)
print("str(dt): ", str(fixed_dt))
print("repr(dt):", repr(fixed_dt))
Output:
str(dt): 2026-10-15 08:30:45.123456
repr(dt): datetime.datetime(2026, 10, 15, 8, 30, 45, 123456)
Implementing __repr__() ensures your objects display cleanly in debugging sessions. If a class defines __repr__() without defining __str__(), Python automatically uses __repr__() as the fallback:
# Implementing __repr__() on custom classes
class Point2D:
def __init__(self, x: float, y: float):
self.x = x
self.y = y
def __repr__(self) -> str:
# Canonical rule: string that looks like a valid constructor call
return f"Point2D(x={self.x}, y={self.y})"
def __str__(self) -> str:
# Friendly informal representation
return f"({self.x}, {self.y})"
pt = Point2D(3.5, 7.2)
print("str(pt): ", str(pt))
print("repr(pt):", repr(pt))
Output:
str(pt): (3.5, 7.2)
repr(pt): Point2D(x=3.5, y=7.2)
Below are real-world recipes utilizing repr() for audit log formatting and invisible whitespace detection:
# Recipe A: Clean interactive debugging logs
class DatabaseRecord:
def __init__(self, table: str, record_id: int, payload: dict):
self.table = table
self.record_id = record_id
self.payload = payload
def __repr__(self) -> str:
return f"DatabaseRecord(table={repr(self.table)}, record_id={self.record_id}, payload={repr(self.payload)})"
rec = DatabaseRecord("users", 101, {"active": True})
print("Audit Log Entry:", repr(rec))
# Recipe B: Debugging invisible whitespace and control characters
suspicious_input = "user_name\t\r\n "
print("Invisible characters exposed via repr():", repr(suspicious_input))
Output:
Audit Log Entry: DatabaseRecord(table='users', record_id=101, payload={'active': True})
Invisible characters exposed via repr(): 'user_name\t\r\n '
__repr__() must return a string. Returning an int or None raises TypeError: __repr__ returned non-string.repr() includes angle brackets (e.g. <file object at ...>) which cannot be evaluated via eval().# Pitfall 1: Failing to define __repr__ leaves default memory address
class BareClass:
pass
# Default object representation is uninformative
print("Default repr:", repr(BareClass()))
# Pitfall 2: Overriding __repr__ returning non-string raises TypeError
class BrokenRepr:
def __repr__(self):
return 12345
try:
repr(BrokenRepr())
except TypeError as err:
print("TypeError caught:", err)
Output:
Default repr: <__main__.BareClass object at ...>
TypeError caught: __repr__ returned non-string (type int)
Practice unambiguous object formatting, eval round-tripping, and custom dunder classes in our companion Jupyter Notebook:
Explore interactive code cells, implement canonical __repr__ methods, test eval reconstruction, and run self-validating assertions.
View on GitHub Run in Google ColabRun these unit checks directly in Python or your local environment to verify repr() mechanics:
def test_repr_mechanics():
# 1. Primitives
assert repr("hello") == "'hello'"
assert repr(42) == "42"
assert repr(None) == "None"
# 2. eval round-trip
data = [1, "two", {"key": 3}]
assert eval(repr(data)) == data
# 3. Custom __repr__
class Item:
def __repr__(self): return "Item(1)"
assert repr(Item()) == "Item(1)"
print("All repr() unit assertions passed! 100% verified.")
test_repr_mechanics()
Output:
All repr() unit assertions passed! 100% verified.
Returns human-readable, friendly string representation of objects.
Parses and evaluates a Python expression string dynamically.
Returns the __dict__ attribute of a module, class, or instance.
Returns the type class of an object or constructs new types.
Author & Instructor at plus2net
I write and maintain practical tutorials on Python, PHP, SQL, JavaScript, HTML, jQuery, and web development at plus2net. The tutorials focus on clear explanations, working examples, and code that readers can test and adapt while learning.