Purpose of __str__ and __repr__ in Python
Before we dive into the discussion, let’s check out the official documentation of Python about these two functions:
object.__repr__(self): called by the
repr() built-in function and by string conversions (reverse quotes) to compute the “official” string representation of an object.
object.__str__(self): called by the
str() build-in function and by the print statement to compute the “informal” string representation of an object.
Quote from Python’s Data Model
From the official documentation, we know that both
__str__ are used to “represent” an object.
__repr__ should be the “official” representation while
__str__ is the “informal” representation.
So, what does Python’s default
__str__ implementation of any object look like?
For example, let’s say we have a
x and a
y and we want to know the return value of
__str__ of these two objects:
>>> x = 1 >>> repr(x) '1' >>> str(x) '1' >>> y = 'a string' >>> repr(y) "'a string'" >>> str(y) 'a string'
While the return of
str() are identical for
int x, you should notice the difference between the return values for
str y. It is important to realize the default implementation of
__repr__ for a
str object can be called as an argument to
eval and the return value would be a valid
>>> repr(y) "'a string'" >>> y2 = eval(repr(y)) >>> y == y2 True
While the return value of
__str__ is not even a valid statement that can be executed by eval:
>>> str(y) 'a string' >>> eval(str(y)) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<string>", line 1 a string ^ SyntaxError: unexpected EOF while parsing
Therefore, a “formal” representation of an object should be callable by eval() and return the same object, if possible. If not possible, such as in the case where the object’s members are referring itself that leads to infinite circular reference, then
__repr__ should be unambiguous and contain as much information as possible.
>>> class ClassA(object): ... def __init__(self, b=None): ... self.b = b ... ... def __repr__(self): ... return '%s(%r)' % (self.__class__, self.b) ... >>> >>> class ClassB(object): ... def __init__(self, a=None): ... self.a = a ... ... def __repr__(self): ... return "%s(%r)" % (self.__class__, self.a) ... >>> a = ClassA() >>> b = ClassB(a=a) >>> a.b = b >>> repr(b) RuntimeError: maximum recursion depth exceeded while calling a Python object
Instead of literally following the requirement of
ClassB which causes an infinite recursion problem where
b.__repr__ which calls
a.__repr__ which calls
b.__repr__, on and on forever, you could define
ClassB.__repr__ in a different way. A way that shows as much information about an object as possible would be just as good as a valid eval-confined
>>> class ClassB(object): ... def __init__(self, a=None): ... self.a = a ... ... def __repr__(self): ... return '%s(a=a)' % (self.__class__) ... >>> a = ClassA() >>> b = ClassB(a=a) >>> a.b = b >>> repr(a) "<class '__main__.ClassA'>(<class '__main__.ClassB'>(a=a))" >>> repr(b) "<class '__main__.ClassB'>(a=a)"
__repr__ is the official representation for an object, you always want to call
"repr(an_object)" to get the most comprehensive information about an object. However, sometimes
__str__ is useful as well. Because
__repr__ could be too complicated to inspect if the object in question is complex (imagine an object with a dozen attributes),
__str__ is helpful to serve as a quick overview of complicated objects. For example, suppose you want to inspect a
datetime object in the middle of a lengthy log file to find out why the
datetime of a user’s photo is not correct:
>>> from datetime import datetime >>> now = datetime.now() >>> repr(now) 'datetime.datetime(2013, 2, 5, 4, 43, 11, 673075)' >>> str(now) '2013-02-05 04:43:11.673075'
__str__ representation of now looks cleaner and easier to read than the formal representation generated from
__repr__. Sometimes, being able to quickly grasp what’s stored in an object is valuable to grab the “big” picture of a complex program.
Gotchas between __str__ and __repr__ in Python
One important catch to keep in mind is that container’s
__str__ uses contained objects’
>>> from datetime import datetime >>> from decimal import Decimal >>> print((Decimal('42'), datetime.now())) (Decimal('42'), datetime.datetime(2013, 2, 5, 4, 53, 32, 646185)) >>> str((Decimal('42'), datetime.now())) "(Decimal('42'), datetime.datetime(2013, 2, 5, 4, 57, 2, 459596))"
Since Python favours unambiguity over readability, the
__str__ call of a tuple calls the contained objects’
__repr__, the “formal” representation of an object. Although the formal representation is harder to read than an informal one, it is unambiguous and more robust against bugs.
Tips and Suggestions between __str__ and __repr__ in Python
__repr__for every class you implement. There should be no excuse.
__str__for classes which you think readability is more important of non-ambiguity.