pyguides

__repr__

__repr__(self)

Purpose and Behavior

The __repr__ method returns a string representation of an object, primarily intended for developers. Unlike __str__, which targets end users, __repr__ is designed to be unambiguous and help developers understand what an object actually is.

Python calls __repr__ automatically in several contexts:

  • When you use repr() on an object
  • When you inspect an object in a debugger
  • When an object appears in an interactive REPL session
  • When objects are contained in collections that need to display them

If you only define __str__ but not __repr__, Python will use __str__ as a fallback when repr() is called. However, defining both is recommended for clarity.

Syntax

def __repr__(self):
    return "..."

The method must return a string. It takes no arguments beyond self.

The Official Convention

Python’s official documentation recommends that __repr__ should return a string that, if passed to eval(), would recreate the object:

class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y
    
    def __repr__(self):
        return f"Point({self.x!r}, {self.y!r})"

p = Point(1, 2)
repr(p)  # 'Point(1, 2)'

Using !r format specifier calls repr() on each value, ensuring strings are quoted correctly.

repr vs str

Both methods return strings, but serve different purposes:

Aspect__repr____str__
AudienceDevelopersEnd users
GoalUnambiguous, debuggableReadable, user-friendly
FallbackUses <...> if not definedFalls back to __repr__ if not defined
class Person:
    def __init__(self, name):
        self.name = name
    
    def __repr__(self):
        return f"Person(name={self.name!r})"
    
    def __str__(self):
        return self.name

p = Person("Alice")
print(str(p))    # Alice (user-friendly)
print(repr(p))  # Person(name='Alice') (developer-friendly)

When to Customize

Customize __repr__ when the default output isn’t helpful:

# Default (not very informative)
class Empty:
    pass

e = Empty()
repr(e)  # '<__main__.Empty object at 0x...>'

# Custom (helpful)
class Empty:
    def __repr__(self):
        return "Empty()"

e = Empty()
repr(e)  # 'Empty()'

Common Patterns

Including Key Attributes

class User:
    def __init__(self, username, email):
        self.username = username
        self.email = email
    
    def __repr__(self):
        return f"User(username={self.username!r}, email={self.email!r})"

Conditional Representations

class Timer:
    def __init__(self, name="Timer"):
        self.name = name
        self.running = False
    
    def __repr__(self):
        state = "running" if self.running else "stopped"
        return f"Timer({self.name!r}, {state})"

# Timer('myTimer', running)
# Timer('myTimer', stopped)

Safe Representations (No eval)

Not all objects can be recreated via eval(). Sometimes a descriptive format is better:

class Connection:
    def __init__(self, host, port, secure):
        self.host = host
        self.port = port
        self.secure = secure
    
    def __repr__(self):
        protocol = "https" if self.secure else "http"
        return f"<Connection to {protocol}://{self.host}:{self.port}>"

conn = Connection("example.com", 443, True)
repr(conn)  # '<Connection to https://example.com:443>'

This is more useful than a string that would fail eval().

See Also