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.
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(lst) + "]")
(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.
__repr__ should return a printable representation of the object, most likely one of the ways possible to create this object. See official documentation here. __repr__ is more for developers while __str__ is for end users.
A simple example:
>>> class Point:
... def __init__(self, x, y):
... self.x, self.y = x, y
... def __repr__(self):
... cls = self.__class__.__name__
... return f'{cls}(x={self.x!r}, y={self.y!r})'
>>> p = Point(1, 2)
>>> p
Point(x=1, y=2)
Best Answer
Alex Martelli summarized well but, surprisingly, was too succinct.
First, let me reiterate the main points in Alex’s post:
__repr__
goal is to be unambiguous__str__
goal is to be readable__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: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 unambiguousLet 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
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 aboutc
. If that’s easy enough, at least in a fuzzy way, do it. If not, make sure you have enough information aboutc
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 userepr()
[or%r
formatting character, equivalently] inside__repr__
implementation, or you’re defeating the goal of repr. You want to be able to differentiateMyClass(3)
andMyClass("3")
.The goal of
__str__
is to be readableSpecifically, 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__
?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
(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.