In this post, we’ll learn the difference between __str__ and __repr__ in Python.
As answered by Ned, my rule of thumb: __repr__
is for developers, __str__
is for customers.
Now, what is the difference between __str__ and __repr__ in Python?
Unless you specifically act to ensure otherwise, most classes don’t have helpful results for either:
>>> class Sic(object): pass
...
>>> print str(Sic())
<__main__.Sic object at 0x8b7d0>
>>> print repr(Sic())
<__main__.Sic object at 0x8b7d0>
>>>
As you see — no difference, and no info beyond the class and object’s id
. If you only override one of the two…:
>>> class Sic(object):
... def __repr__(object): return 'foo'
...
>>> print str(Sic())
foo
>>> print repr(Sic())
foo
>>> class Sic(object):
... def __str__(object): return 'foo'
...
>>> print str(Sic())
foo
>>> print repr(Sic())
<__main__.Sic object at 0x2617f0>
>>>
as you see, if you override __repr__
, that’s ALSO used for __str__
, but not vice versa.
Other crucial tidbits to know: __str__
on a built-on container uses the __repr__
, NOT the __str__
, for the items it contains. And, despite the words on the subject found in typical docs, hardly anybody bothers making the __repr__
of objects be a string that eval
may use to build an equal object (it’s just too hard, AND not knowing how the relevant module was actually imported makes it actually flat out impossible).
So, my advice: focus on making __str__
reasonably human-readable, and __repr__
as unambiguous as you possibly can, even if that interferes with the fuzzy unattainable goal of making __repr__
‘s returned value is acceptable as input to __eval__
!
The answer to this point is quite a nice summary but, surprisingly, was too succinct.
First, let me reiterate the main points mentioned until now:
- The default implementation is useless (it’s hard to think of one which wouldn’t be, but yeah)
__repr__
goal is to be unambiguous__str__
goal is to be readable- Container’s
__str__
uses contained objects’__repr__
Default implementation is useless
This is mostly a surprise because Python’s defaults tend to be fairly useful. However, in this case, having a default for __repr__
which would act like:
return "%s(%r)" % (self.__class__, self.__dict__)
would have been too dangerous (for example, too easy to get into infinite recursion if objects reference each other). So Python cops out. Note that there is one default which is true: if __repr__
is defined, and __str__
is not, the object will behave as though __str__=__repr__
.
This means, in simple terms: almost every object you implement should have a functional __repr__
that’s usable for understanding the object. Implementing __str__
is optional: do that if you need a “pretty print” functionality (for example, used by a report generator).
The goal of __repr__
is to be unambiguous
Let me come right out and say it — I do not believe in debuggers. I don’t really know how to use any debugger, and have never used one seriously. Furthermore, I believe that the big fault in debuggers is their basic nature — most failures I debug happened a long long time ago, in a galaxy far far away. This means that I do believe, with religious fervor, in logging. Logging is the lifeblood of any decent fire-and-forget server system. Python makes it easy to log: with maybe some project specific wrappers, all you need is a
log(INFO, "I am in the weird function and a is", a, "and b is", b, "but I got a null C — using default", default_c)
But you have to do the last step — make sure every object you implement has a useful repr, so code like that can just work. This is why the “eval” thing comes up: if you have enough information so eval(repr(c))==c
, that means you know everything there is to know about c
. If that’s easy enough, at least in a fuzzy way, do it. If not, make sure you have enough information about c
anyway. I usually use an eval-like format: "MyClass(this=%r,that=%r)" % (self.this,self.that)
. It does not mean that you can actually construct MyClass, or that those are the right constructor arguments — but it is a useful form to express “this is everything you need to know about this instance”.
Note: I used %r
above, not %s
. You always want to use repr()
[or %r
formatting character, equivalently] inside __repr__
implementation, or you’re defeating the goal of repr. You want to be able to differentiate MyClass(3)
and MyClass("3")
.
The goal of __str__
is to be readable
Specifically, it is not intended to be unambiguous — notice that str(3)==str("3")
. Likewise, if you implement an IP abstraction, having the str of it look like 192.168.1.1 is just fine. When implementing a date/time abstraction, the str can be “2010/4/12 15:35:22”, etc. The goal is to represent it in a way that a user, not a programmer, would want to read it. Chop off useless digits, pretend to be some other class — as long is it supports readability, it is an improvement.
Container’s __str__
uses contained objects’ __repr__
This seems surprising, doesn’t it? It is a little, but how readable would it be if it used their __str__
?
[moshe is, 3, hello
world, this is a list, oh I don't know, containing just 4 elements]
Not very. Specifically, the strings in a container would find it way too easy to disturb its string representation. In the face of ambiguity, remember, Python resists the temptation to guess. If you want the above behavior when you’re printing a list, just
print "[" + ", ".join(l) + "]"
(you can probably also figure out what to do about dictionaries.
Summary
Implement __repr__
for any class you implement. This should be second nature. Implement __str__
if you think it would be useful to have a string version which errs on the side of readability.
Answer #2:
What is the difference between __str__
and __repr__
in Python?
__str__
(read as “dunder (double-underscore) string”) and __repr__
(read as “dunder-repper” (for “representation”)) are both special methods that return strings based on the state of the object.
__repr__
provides backup behavior if __str__
is missing.
So one should first write a __repr__
that allows you to reinstantiate an equivalent object from the string it returns e.g. using eval
or by typing it in character-for-character in a Python shell.
At any time later, one can write a __str__
for a user-readable string representation of the instance, when one believes it to be necessary.
__str__
If you print an object, or pass it to format
, str.format
, or str
, then if a __str__
method is defined, that method will be called, otherwise, __repr__
will be used.
__repr__
The __repr__
method is called by the builtin function repr
and is what is echoed on your python shell when it evaluates an expression that returns an object.
Since it provides a backup for __str__
, if you can only write one, start with __repr__
Here’s the builtin help on repr
:
repr(...)
repr(object) -> string
Return the canonical string representation of the object.
For most object types, eval(repr(object)) == object.
That is, for most objects, if you type in what is printed by repr
, you should be able to create an equivalent object. But this is not the default implementation.
Default Implementation of __repr__
The default object __repr__
is something like:
def __repr__(self):
return '<{0}.{1} object at {2}>'.format(
self.__module__, type(self).__name__, hex(id(self)))
That means by default you’ll print the module the object is from, the class name, and the hexadecimal representation of its location in memory – for example:
<__main__.Foo object at 0x7f80665abdd0>
This information isn’t very useful, but there’s no way to derive how one might accurately create a canonical representation of any given instance, and it’s better than nothing, at least telling us how we might uniquely identify it in memory.
How can __repr__
be useful?
Let’s look at how useful it can be, using the Python shell and datetime
objects. First we need to import the datetime
module:
import datetime
If we call datetime.now
in the shell, we’ll see everything we need to recreate an equivalent datetime object. This is created by the datetime __repr__
:
>>> datetime.datetime.now()
datetime.datetime(2015, 1, 24, 20, 5, 36, 491180)
If we print a datetime object, we see a nice human readable (in fact, ISO) format. This is implemented by datetime’s __str__
:
>>> print(datetime.datetime.now())
2015-01-24 20:05:44.977951
It is a simple matter to recreate the object we lost because we didn’t assign it to a variable by copying and pasting from the __repr__
output, and then printing it, and we get it in the same human readable output as the other object:
>>> the_past = datetime.datetime(2015, 1, 24, 20, 5, 36, 491180)
>>> print(the_past)
2015-01-24 20:05:36.491180
How do I implement them?
As you’re developing, you’ll want to be able to reproduce objects in the same state, if possible. This, for example, is how the datetime object defines __repr__
. It is fairly complex, because of all of the attributes needed to reproduce such an object:
def __repr__(self):
"""Convert to formal string, for repr()."""
L = [self._year, self._month, self._day, # These are never zero
self._hour, self._minute, self._second, self._microsecond]
if L[-1] == 0:
del L[-1]
if L[-1] == 0:
del L[-1]
s = "%s.%s(%s)" % (self.__class__.__module__,
self.__class__.__qualname__,
", ".join(map(str, L)))
if self._tzinfo is not None:
assert s[-1:] == ")"
s = s[:-1] + ", tzinfo=%r" % self._tzinfo + ")"
if self._fold:
assert s[-1:] == ")"
s = s[:-1] + ", fold=1)"
return s
If you want your object to have a more human readable representation, you can implement __str__
next. Here’s how the datetime object implements __str__
, which it easily does because it already has a function to display it in ISO format:
def __str__(self):
"Convert to string, for str()."
return self.isoformat(sep=' ')
Set __repr__ = __str__
?
This is a critique of another answer here that suggests setting __repr__ = __str__
.
Setting __repr__ = __str__
is silly – __repr__
is a fallback for __str__
and a __repr__
, written for developers usage in debugging, should be written before you write a __str__
.
You need a __str__
only when you need a textual representation of the object.
Conclusion
Define __repr__
for objects you write so you and other developers have a reproducible example when using it as you develop. Define __str__
when you need a human readable string representation of it.
Answer #3:
Apart from all the answers given, I would like to add few points :-
1) __repr__()
is invoked when you simply write object’s name on interactive python console and press enter.
2) __str__()
is invoked when you use object with print statement.
3) In case, if __str__
is missing, then print and any function using str()
invokes __repr__()
of object.
4) __str__()
of containers, when invoked will execute __repr__()
method of its contained elements.
5) str()
called within __str__()
could potentially recurse without a base case, and error on maximum recursion depth.
6) __repr__()
can call repr()
which will attempt to avoid infinite recursion automatically, replacing an already represented object with ...
.
Summary:
In short, the goal of
__repr__
is to be unambiguous and__str__
is to be readable.
Here is a good example:
>>> import datetime
>>> today = datetime.datetime.now()
>>> str(today)
'2012-03-14 09:21:58.130922'
>>> repr(today)
'datetime.datetime(2012, 3, 14, 9, 21, 58, 130922)'
Read this documentation for repr:
repr(object)
Return a string containing a printable representation of an object. This is the same value yielded by conversions (reverse quotes). It is sometimes useful to be able to access this operation as an ordinary function. For many types, this function makes an attempt to return a string that would yield an object with the same value when passed to
eval()
, otherwise the representation is a string enclosed in angle brackets that contains the name of the type of the object together with additional information often including the name and address of the object. A class can control what this function returns for its instances by defining a__repr__()
method.
Here is the documentation for str:
str(object='')
Return a string containing a nicely printable representation of an object. For strings, this returns the string itself. The difference with
repr(object)
is thatstr(object)
does not always attempt to return a string that is acceptable toeval()
; its goal is to return a printable string. If no argument is given, returns the empty string,''
.
Hope you learned something from this post.
Follow Programming Articles for more!