Logo

What is the difference between __str__ and __repr__ in Python?

Demystifying __str__ vs. __repr__ in Python

In Python, both __str__ and __repr__ are special (dunder) methods designed to provide string representations of objects. Although they share similarities, they serve distinct purposes and are intended for different audiences:

  1. Primary Intent

    • __repr__: Aimed at developers. Its return value should be an unambiguous, preferably evaluable, representation of an object, often used for debugging or logging. Ideally, __repr__ should produce a string that, when passed to eval(), creates the same object. If that’s not feasible, it should at least provide a clear and detailed description that lets programmers identify the object’s nature and state.
    • __str__: Aimed at end-users. Its return value should be a readable, user-friendly representation of the object. While __repr__ is about internal details and clarity for debugging, __str__ focuses on presenting a “nice” and understandable description. If an object only defines __repr__ but not __str__, calling str(object) will default to __repr__.
  2. Default Behavior

    • If you don’t implement __str__, calling str(object) falls back to calling __repr__.
    • If you don’t implement __repr__, the default representation includes the object’s type and memory address, which is not very informative but ensures you always have some representation for debugging.
  3. Use Cases

    • __repr__: Use it for logging, debugging, and error messages. When a developer inspects objects in a REPL session or logs them, __repr__ should provide valuable insights.
    • __str__: Use it when you want a clean, human-readable string—like when displaying data to users, printing reports, or generating UI output. __str__ often omits unnecessary technical details since end-users don’t need them.

Example:

class Point: def __init__(self, x, y): self.x = x self.y = y def __repr__(self): # Unambiguous representation for developers return f"Point(x={self.x}, y={self.y})" def __str__(self): # User-friendly representation return f"({self.x}, {self.y})" p = Point(3, 4) print(repr(p)) # Output: Point(x=3, y=4) print(str(p)) # Output: (3, 4)

In this example, __repr__ gives a more “official” and detailed output, suitable for debugging. __str__ provides a cleaner, user-friendly representation.

Why Does This Matter?
Distinguishing between __str__ and __repr__ helps you write classes that are both easy to debug and pleasant to display. It promotes cleaner logging, simpler debugging, and better user experiences when your objects produce meaningful textual output tailored to their audience.

Strengthening Your Python Foundations
Understanding how to craft __str__ and __repr__ methods is one of the many nuances that can elevate your Python coding from functional to professional-grade.

  • Grokking Python Fundamentals: Ideal for beginners, this course helps you build a strong understanding of Python’s object model, including best practices for implementing methods like __str__ and __repr__.

For more advanced problem-solving and interview prep, consider:

To supplement your learning, explore the DesignGurus.io YouTube channel, where you’ll find insights, tutorials, and tips on Python best practices, system design principles, and more.

In Summary

  • __repr__: Developer-focused, detailed, and unambiguous. Best for debugging and logging.
  • __str__: User-focused, simplified, and readable. Best for end-user interaction and output formatting.

By properly leveraging these two methods, you can make your classes more intuitive, debuggable, and user-friendly—a must for any professional-grade Python application.

TAGS
Python
CONTRIBUTOR
TechGrind