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:
-
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 toeval()
, 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__
, callingstr(object)
will default to__repr__
.
-
Default Behavior
- If you don’t implement
__str__
, callingstr(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.
- If you don’t implement
-
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:
- Grokking the Coding Interview: Patterns for Coding Questions: Learn common coding patterns to approach interview questions systematically.
- Grokking Data Structures & Algorithms for Coding Interviews: Strengthen your algorithmic thinking, enabling you to handle complex scenarios elegantly.
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.