What is the difference between __str__ and __repr__?
Solution 1
Alex summarized well but, surprisingly, was too succinct.
First, let me reiterate the main points in Alex’s post:
- 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.
Solution 2
My rule of thumb: __repr__
is for developers, __str__
is for customers.
Solution 3
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__(self): return 'foo'
...
>>> print(str(Sic()))
foo
>>> print(repr(Sic()))
foo
>>> class Sic(object):
... def __str__(self): 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 acceptable as input to __eval__
!
Solution 4
__repr__
: representation of python object usually eval will convert it back to that object
__str__
: is whatever you think is that object in text form
e.g.
>>> s="""w'o"w"""
>>> repr(s)
'\'w\\\'o"w\''
>>> str(s)
'w\'o"w'
>>> eval(str(s))==s
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<string>", line 1
w'o"w
^
SyntaxError: EOL while scanning single-quoted string
>>> eval(repr(s))==s
True
Solution 5
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,''
.
Casebash
Bachelor of Science (Adv Maths) with Honors in Computer Science from University of Sydney Programming C/C++/Java/Python/Objective C/C#/Javascript/PHP
Updated on April 28, 2022Comments
-
Casebash about 2 years
-
Steven T. Snyder over 12 yearsIn my unit tests I always check that
eval(repr(foo))
evaluates to an object equal tofoo
. You're right that it won't work outside of my test cases since I don't know how the module is imported, but this at least ensures that it works in some predictable context. I think this a good way of evaluating if the result of__repr__
is explicit enough. Doing this in a unit test also helps ensure that__repr__
follows changes to the class. -
jwg about 10 yearsI think this misses the point. The use of
eval(repr(obj))
is a sanity test and a rule of thumb - if this recreates the original object correctly then you have a decent__repr__
implementation. It's not intended that you actually serialize objects this way. -
abarnert almost 10 yearsI always try to make sure that either
eval(repr(spam)) == spam
(at least in the right context), oreval(repr(spam))
raises aSyntaxError
. That way you avoid confusion. (And that's almost true for the builtins and most of the stdlib, except for, e.g., recursive lists, wherea=[]; a.append(a); print(eval(repr(a)))
gives you[[Ellipses]]
…) Of course I don't do that to actually useeval(repr(spam))
, except as a sanity check in unit tests… but I do sometimes copy and pasterepr(spam)
into an interactive session. -
Samuel over 9 yearsDefinitely disagree with your opinion that debugging isn't the way to go. For development use a debugger (and/or logging), for production use logging. With a debugger you have a view of everything that went wrong when the problem occurred. You can see the full picture. Unless you are logging EVERYTHING you can't get that. Plus if you are logging everything you're going have to wade through tons of data to get at what you want.
-
ThatAintWorking over 9 yearsGreat answer (except the bit about not using debuggers). I'd just like to add a link to this other Q&A about str vs unicode in Python 3 which could be relevant to the discussion for people who have made the switch.
-
Luis Masuelli over 8 years
eval
is not inherently dangerous. Is not more dangerous thanunlink
,open
, or writing to files. Should we stop writing to files because perhaps a malicious attack could use an arbitrary file path to put content inside? Everything is dangerous if dumbly used by dumb people. Idiocy is dangerous. Dunning-Kruger effects are dangerous.eval
is just a function. -
Mad Physicist over 6 years
__repr__
is by no means required to return a vaild Python expression. -
SuperGeo over 6 yearsWhy would not containers (lists, tuples) use
__str__
for each element instead of__repr__
? Seems plain wrong to me, as I implemented a readable__str__
in my object and when it is part of a list I see the uglier__repr__
instead. -
Vicrobot almost 6 yearsWhat is the meaning of printable string here? Can you explain it please?
-
Solomon Ucko over 5 yearsShouldn't it be something along the lines of
type(obj).__qualname__
? -
Russia Must Remove Putin over 5 years@SolomonUcko yes in Python 3, that would seem to be the case - I've been hunting down the source code where this is implemented and I'll update my answer with that information when I get it together.
-
jiten over 5 yearsIt is at pg. #351.
-
jiten over 5 yearsIt uses
__repr__
when it (__str__
) is not defined! So, you are wrong. -
ilias iliadis over 5 years@moshez worth mentioning that containers (lists, dicts) always use the
__repr__
and not the__str__
. Theprint(str([today, today]))
prints[datetime.datetime(2019, 1, 8, 20, 5, 27, 24162), datetime.datetime(2019, 1, 8, 20, 5, 27, 24162)]
. -
max over 5 yearsJust ran into an annoying bug related to the fact that
eval(repr(x))
fails even for builtin types:class A(str, Enum): X = 'x'
will raise SyntaxError oneval(repr(A.X))
. It's sad, but understandable. BTW,eval(str(A.X))
actually works, but of course only ifclass A
is in scope -- so it's probably not very useful. -
Naren Yellavula about 5 yearsThis is true because for obj = uuid.uuid1(), obj.__str__() is "2d7fc7f0-7706-11e9-94ae-0242ac110002" and obj.__repr__() is "UUID('2d7fc7f0-7706-11e9-94ae-0242ac110002')". Developers need (value + origin) whereas customers need a value and they don't care how they got it!
-
NelsonGon about 5 yearsIs
eval(repr())
safe for use in say an API module that stores user passwords? -
NelsonGon about 5 yearsIt's kind of misleading to refer to
repr
as reproduce. It is better to think of it as represent. -
hans almost 5 yearsI heard that a variable
l
(lowercase letter "L") will be syntax error in python 4.0 ;) -
RedGlyph almost 5 yearson debugger vs no debugger: don't get such entrenched opinions. In some applications debugging is not realistic, typically when real-time is involved, or when your code only executes remotely on a platform with little access or no console. In most other cases it will be much quicker to stop at an exception to investigate, or to set a breakpoint, because you don't have to go through thousands of lines of logging (which will clutter your disk and slow down the application). Finally, it's not always possible to log, for example on embedded devices, there debugger is your friend too.
-
mtraceur over 4 years@SuperGeo Other answers cover this: container
str
use elementrepr
because[1, 2, 3]
!=["1", "2, 3"]
. -
Shiplu Mokaddim over 4 yearsHere customer may not necessarily mean end-user. It's the client or user of the object. So if its an SDK then the SDK developers will use
__str__
so normal developers have readable object. On the other hand,__repr__
is for the SDK developers themselves. -
Marco Sulla over 4 yearsAbout debuggging vs logging, they are both useful. If a bug is reproducible, debugging is more simple. If the bug is randomic, logging is essential.
-
Philip Couling over 4 years@RedGlyph "when your code only executes remotely on a platform" is a code smell. It implicitly has no unit tests etc... A better example might be debugging rare stochastic (non-deterministic) bugs, IE bugs that are not easily reproducible. Emphasis on the issue requiring the remote platform not the code.
-
PSK0007 almost 4 yearsbuilding upon the above example by "bitoffdev" and @deadly we can see how str is for the end user because it only gives us a readable string where as repr is fro developers because it gives us the value as well as the type. If you are looking for interview answers then it would be perfect.
-
RedGlyph almost 4 years@PhilipCouling Be sure to read carefully and use the proper vocabulary before lessening others' answers and comments. We use "code smell" when reading the code reveals something that needs refactoring because it hides a potential problem that may trigger difficult-to-find bugs later, or generate a bad overall structure. Having unit test or not is not something you can suppose at this point either (and it's definitely not "implicit"). Finally, your claim of a "better example" has no basis whatsoever, I've actually used a debugger to solve those issues many times where logging was inappropriate.
-
Philip Couling almost 4 years@RedGlyph I'm aware if it's meaning. Code that can only be executed only remotely indeed does make it harder to test, it infers the need for some remote resource. Unit testing would often mock or stub such resources leading back to "why can't the code be executed locally". If code really can't attach to a debugger I'd be concerned what bugs have been hidden as a result of poor testing. I do believe that true "remote only" code should be discouraged. You say you've used a debugger on "bugs that are not easily reproducible". That's a bold claim.
-
djvg over 3 years@abarnert: for a custom
class Spam
,eval(repr(spam)) == spam
would requireSpam.__eq__
to be implemented as well, right? By defaultobject.__eq__
usesis
(docs). -
joanis about 3 yearsA small update for recent versions of Python 3: you can use f-strings and still invoke the
__repr__
of data you embed, by adding!r
: you can replace"MyClass(this=%r,that=%r)" % (self.this,self.that)
byf"MyClass(this={self.this!r},that={self.that!r})"
. Otherwise, thanks for this great post! -
Mark Ransom over 2 years@NarenYellavula if you're exposing a UUID to a customer you're probably doing something wrong.
-
Tarun Kumar over 2 years__repr__() : used to create "constructor-like expression" in string, so that eval() can re-construct an object back from this string representation __str__() : used to create string containing a printable representation of an object
-
avimimoun over 2 yearsMeaby
return "%s(**%r)" % (self.__class__, self.__dict__)
-
Gokul nath over 2 yearsThis answer will be more helpful for beginners. Nice explanation!!
-
Maggyero about 2 yearsI have changed
self.__module__
totype(self).__module__
(since for exemple3
has no__module__
) andtype(self).__name__
totype(self).__qualname__
(since for instance withclass A: class B: pass
that is whatrepr(A.B())
returns). -
Abdessabour Mtk about 2 years@MarkRansom why is that?
-
Mark Ransom about 2 years@AbdessabourMtk they're overly complex, and there's no protection against typing them wrong. Maybe in certain contexts like as part of a QR code they would be OK.
-
Abdessabour Mtk about 2 years@MarkRansom thanks for the quick response. I thought it was something "security" related