Difference between __str__ and __repr__?
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}
What is the difference between __str__
and __repr__
in Python
?
python magic-methods repr
add a comment |
What is the difference between __str__
and __repr__
in Python
?
python magic-methods repr
add a comment |
What is the difference between __str__
and __repr__
in Python
?
python magic-methods repr
What is the difference between __str__
and __repr__
in Python
?
python magic-methods repr
python magic-methods repr
edited Apr 25 '18 at 18:06
martineau
70.4k1093186
70.4k1093186
asked Sep 17 '09 at 4:27
CasebashCasebash
49.5k73210321
49.5k73210321
add a comment |
add a comment |
21 Answers
21
active
oldest
votes
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
[moshe is, 3, hello
world, this is a list, oh I don't know, containing just 4 elements]
be? 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.
67
Definitely 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.
– Samuel
Feb 21 '15 at 19:06
12
Great 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.
– ThatAintWorking
Mar 23 '15 at 21:04
31
", ".join(l)
- uses bad practice of using lowercase letter "L" as variable name. Let's don't teach programming newbies such examples in authoritative sources.
– Nikolay Prokopyev
Feb 16 '17 at 13:30
7
plus1 for debuggers are useless, and don't scale worth a dime. Get your logging throughput up instead. And yes this was a well-written post. Turns out__repr__
was what I needed for debugging. Thank you for your help.
– personal_cloud
Sep 29 '17 at 15:43
3
your debugger folly aside, i learnt the %r and that's worth the vote anyway
– Mickey Perlstein
Dec 13 '18 at 9:21
|
show 1 more comment
My rule of thumb: __repr__
is for developers, __str__
is for customers.
add a comment |
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 acceptable as input to __eval__
!
28
In my unit tests I always check thateval(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.
– Steven T. Snyder
Nov 15 '11 at 19:58
2
I always try to make sure that eithereval(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.
– abarnert
Sep 20 '14 at 5:34
plus1 for explaining that__str__
is implemented in terms of__repr__
. Seems to be something the other posts missed.
– personal_cloud
Sep 29 '17 at 15:45
Why 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.
– SuperGeo
Jan 26 '18 at 14:15
Just ran into an annoying bug related to the fact thateval(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.
– max
Jan 13 at 13:26
|
show 1 more comment
__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
add a comment |
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 toeval()
, 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 withrepr(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,''
.
1
What is the meaning of printable string here? Can you explain it please?
– Vicrobot
Aug 19 '18 at 5:44
add a comment |
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 (C Python source) 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__
(Python source). 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 = ", ".join(map(str, L))
s = "%s(%s)" % ('datetime.' + self.__class__.__name__, s)
if self._tzinfo is not None:
assert s[-1:] == ")"
s = s[:-1] + ", tzinfo=%r" % self._tzinfo + ")"
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 (Python source) 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.
Shouldn't it be something along the lines oftype(obj).__qualname__
?
– Solomon Ucko
Dec 1 '18 at 1:10
@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.
– Aaron Hall♦
Dec 1 '18 at 20:50
add a comment |
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 ...
.
add a comment |
On page 358 of the book Python scripting for computational science by Hans Petter Langtangen, it clearly states that
- The
__repr__
aims at a complete string representation of the object; - The
__str__
is to return a nicely string for printing.
So, I prefer to understand them as
- repr = reproduce
- str = string (representation)
from the user point of view
although this is a misunderstanding i made when learning python.
A small but good example is also given on the same page as follows:
Example
In [38]: str('s')
Out[38]: 's'
In [39]: repr('s')
Out[39]: "'s'"
In [40]: eval(str('s'))
Traceback (most recent call last):
File "<ipython-input-40-abd46c0c43e7>", line 1, in <module>
eval(str('s'))
File "<string>", line 1, in <module>
NameError: name 's' is not defined
In [41]: eval(repr('s'))
Out[41]: 's'
It is at pg. #351.
– jiten
Dec 21 '18 at 13:10
add a comment |
In all honesty, eval(repr(obj))
is never used. If you find yourself using it, you should stop, because eval
is dangerous, and strings are a very inefficient way to serialize your objects (use pickle
instead).
Therefore, I would recommend setting __repr__ = __str__
. The reason is that str(list)
calls repr
on the elements (I consider this to be one of the biggest design flaws of Python that was not addressed by Python 3). An actual repr
will probably not be very helpful as the output of print [your, objects]
.
To qualify this, in my experience, the most useful use case of the repr
function is to put a string inside another string (using string formatting). This way, you don't have to worry about escaping quotes or anything. But note that there is no eval
happening here.
18
I think this misses the point. The use ofeval(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.
– jwg
Jun 6 '14 at 13:56
6
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.
– Luis Masuelli
Mar 1 '16 at 15:12
add a comment |
To put it simply:
__str__
is used in to show a string representation of your object to be read easily by others.
__repr__
is used to show a string representation of the object.
Let's say I want to create a Fraction
class where the string representation of a fraction is '(1/2)' and the object (Fraction class) is to be represented as 'Fraction (1,2)'
So we can create a simple Fraction class:
class Fraction:
def __init__(self, num, den):
self.__num = num
self.__den = den
def __str__(self):
return '(' + str(self.__num) + '/' + str(self.__den) + ')'
def __repr__(self):
return 'Fraction (' + str(self.__num) + ',' + str(self.__den) + ')'
f = Fraction(1,2)
print('I want to represent the Fraction STRING as ' + str(f)) # (1/2)
print('I want to represent the Fraction OBJECT as ', repr(f)) # Fraction (1,2)
add a comment |
From http://pyref.infogami.com/__str__ by effbot:
__str__
"computes the "informal" string representation of an object. This differs from __repr__
in that it does not have to be a valid Python expression: a more convenient or concise representation may be used instead."
2
__repr__
is by no means required to return a vaild Python expression.
– Mad Physicist
Oct 20 '17 at 3:23
add a comment |
One aspect that is missing in other answers. It's true that in general the pattern is:
- Goal of
__str__
: human-readable - Goal of
__repr__
: unambiguous, possibly machine-readable viaeval
Unfortunately, this differentiation is flawed, because the Python REPL and also IPython use __repr__
for printing objects in a REPL console (see related questions for Python and IPython). Thus, projects which are targeted for interactive console work (e.g., Numpy or Pandas) have started to ignore above rules and provide a human-readable __repr__
implementation instead.
1
I was wondering about this
– The Unfun Cat
Apr 15 '18 at 18:47
add a comment |
str
- Creates a new string object from the given object.
repr
- Returns the canonical string representation of the object.
The differences:
str():
- makes object readable
- generates output for end-user
repr():
- needs code that reproduces object
- generates output for developer
add a comment |
"A basic requirement for a Python object is to provide usable
string representations of itself, one used for debugging and
logging, another for presentation to end users. That is why the
special methods __repr__ and __str__ exist in the data model."
From the book: Fluent Python
add a comment |
Excellent answers already cover the difference between __str__
and __repr__
, which for me boils down to the former being readable even by an end user, and the latter being as useful as possible to developers. Given that, I find that the default implementation of __repr__
often fails to achieve this goal because it omits information useful to developers.
For this reason, if I have a simple enough __str__
, I generally just try to get the best of both worlds with something like:
def __repr__(self):
return '{0} ({1})'.format(object.__repr__(self), str(self))
add a comment |
>>> print(decimal.Decimal(23) / decimal.Decimal("1.05"))
21.90476190476190476190476190
>>> decimal.Decimal(23) / decimal.Decimal("1.05")
Decimal('21.90476190476190476190476190')
When print() is called on the result of decimal.Decimal(23) / deci- mal.Decimal("1.05") the raw number is printed; this output is in string form which can be achieved with __str __(). If we simply enter the expression we get a decimal.Decimal output—this output is in representational form which can be achieved with __repr __(). All Python objects have two output forms. String form is designed to be human-readable. Representational form is designed to produce output that if fed to a Python interpreter would (when possible) re- produce the represented object
add a comment |
One important thing to keep in mind is that container's
__str__
uses contained objects'__repr__
.
>>> from datetime import datetime
>>> from decimal import Decimal
>>> print (Decimal('52'), datetime.now())
(Decimal('52'), datetime.datetime(2015, 11, 16, 10, 51, 26, 185000))
>>> str((Decimal('52'), datetime.now()))
"(Decimal('52'), datetime.datetime(2015, 11, 16, 10, 52, 22, 176000))"
Python favors 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.
It uses__repr__
when it (__str__
) is not defined! So, you are wrong.
– jiten
Dec 21 '18 at 13:48
add a comment |
So much clearer
from blog
str is like toString. created so you can print the data
repr is like serialize, or pickle. How do i recreate this object if i need to do so using eval()
>>> import datetime
>>> now = datetime.datetime.now()
>>> str(now)
'2015-04-04 20:51:31.766862'
>>> repr(now)
'datetime.datetime(2015, 4, 4, 20, 51, 31, 766862)'
>>mydate = eval(repr(now))
add a comment |
In a nutshell:
class Demo:
def __repr__(self):
return 'repr'
def __str__(self):
return 'str'
demo = Demo()
print(demo) # use __str__, output 'str' to stdout
s = str(demo) # __str__ is used, return 'str'
r = repr(demo) # __repr__ is used, return 'repr'
import logging
logger = logging.getLogger(logging.INFO)
logger.info(demo) # use __str__, output 'str' to stdout
from pprint import pprint, pformat
pprint(demo) # use __repr__, output 'repr' to stdout
result = pformat(demo) # use __repr__, result is string which value is 'str'
add a comment |
Understand __str__
and __repr__
intuitively and permanently distinguish them at all.
__str__
return the string disguised body of a given object for readable of eyes__repr__
return the real flesh body of a given object (return itself) for unambiguity to identify.
See it in an example
In [30]: str(datetime.datetime.now())
Out[30]: '2017-12-07 15:41:14.002752'
Disguised in string form
As to __repr__
In [32]: datetime.datetime.now()
Out[32]: datetime.datetime(2017, 12, 7, 15, 43, 27, 297769)
Presence in real body which allows to be manipulated directly.
We can do arithmetic operation on __repr__
results conveniently.
In [33]: datetime.datetime.now()
Out[33]: datetime.datetime(2017, 12, 7, 15, 47, 9, 741521)
In [34]: datetime.datetime(2017, 12, 7, 15, 47, 9, 741521) - datetime.datetime(2
...: 017, 12, 7, 15, 43, 27, 297769)
Out[34]: datetime.timedelta(0, 222, 443752)
if apply the operation on __str__
In [35]: '2017-12-07 15:43:14.002752' - '2017-12-07 15:41:14.002752'
TypeError: unsupported operand type(s) for -: 'str' and 'str'
Returns nothing but error.
Another example.
In [36]: str('string_body')
Out[36]: 'string_body' # in string form
In [37]: repr('real_body')
Out[37]: "'real_body'" #its real body hide inside
Hope this help you build concrete grounds to explore more answers.
add a comment |
__repr__
is used everywhere, except by print
and str
when a __str__
is defined
add a comment |
21 Answers
21
active
oldest
votes
21 Answers
21
active
oldest
votes
active
oldest
votes
active
oldest
votes
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
[moshe is, 3, hello
world, this is a list, oh I don't know, containing just 4 elements]
be? 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.
67
Definitely 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.
– Samuel
Feb 21 '15 at 19:06
12
Great 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.
– ThatAintWorking
Mar 23 '15 at 21:04
31
", ".join(l)
- uses bad practice of using lowercase letter "L" as variable name. Let's don't teach programming newbies such examples in authoritative sources.
– Nikolay Prokopyev
Feb 16 '17 at 13:30
7
plus1 for debuggers are useless, and don't scale worth a dime. Get your logging throughput up instead. And yes this was a well-written post. Turns out__repr__
was what I needed for debugging. Thank you for your help.
– personal_cloud
Sep 29 '17 at 15:43
3
your debugger folly aside, i learnt the %r and that's worth the vote anyway
– Mickey Perlstein
Dec 13 '18 at 9:21
|
show 1 more comment
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
[moshe is, 3, hello
world, this is a list, oh I don't know, containing just 4 elements]
be? 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.
67
Definitely 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.
– Samuel
Feb 21 '15 at 19:06
12
Great 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.
– ThatAintWorking
Mar 23 '15 at 21:04
31
", ".join(l)
- uses bad practice of using lowercase letter "L" as variable name. Let's don't teach programming newbies such examples in authoritative sources.
– Nikolay Prokopyev
Feb 16 '17 at 13:30
7
plus1 for debuggers are useless, and don't scale worth a dime. Get your logging throughput up instead. And yes this was a well-written post. Turns out__repr__
was what I needed for debugging. Thank you for your help.
– personal_cloud
Sep 29 '17 at 15:43
3
your debugger folly aside, i learnt the %r and that's worth the vote anyway
– Mickey Perlstein
Dec 13 '18 at 9:21
|
show 1 more comment
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
[moshe is, 3, hello
world, this is a list, oh I don't know, containing just 4 elements]
be? 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.
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
[moshe is, 3, hello
world, this is a list, oh I don't know, containing just 4 elements]
be? 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.
edited Feb 20 at 18:19
user443854
2,416113152
2,416113152
answered Apr 13 '10 at 0:56
moshezmoshez
25.4k11513
25.4k11513
67
Definitely 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.
– Samuel
Feb 21 '15 at 19:06
12
Great 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.
– ThatAintWorking
Mar 23 '15 at 21:04
31
", ".join(l)
- uses bad practice of using lowercase letter "L" as variable name. Let's don't teach programming newbies such examples in authoritative sources.
– Nikolay Prokopyev
Feb 16 '17 at 13:30
7
plus1 for debuggers are useless, and don't scale worth a dime. Get your logging throughput up instead. And yes this was a well-written post. Turns out__repr__
was what I needed for debugging. Thank you for your help.
– personal_cloud
Sep 29 '17 at 15:43
3
your debugger folly aside, i learnt the %r and that's worth the vote anyway
– Mickey Perlstein
Dec 13 '18 at 9:21
|
show 1 more comment
67
Definitely 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.
– Samuel
Feb 21 '15 at 19:06
12
Great 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.
– ThatAintWorking
Mar 23 '15 at 21:04
31
", ".join(l)
- uses bad practice of using lowercase letter "L" as variable name. Let's don't teach programming newbies such examples in authoritative sources.
– Nikolay Prokopyev
Feb 16 '17 at 13:30
7
plus1 for debuggers are useless, and don't scale worth a dime. Get your logging throughput up instead. And yes this was a well-written post. Turns out__repr__
was what I needed for debugging. Thank you for your help.
– personal_cloud
Sep 29 '17 at 15:43
3
your debugger folly aside, i learnt the %r and that's worth the vote anyway
– Mickey Perlstein
Dec 13 '18 at 9:21
67
67
Definitely 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.
– Samuel
Feb 21 '15 at 19:06
Definitely 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.
– Samuel
Feb 21 '15 at 19:06
12
12
Great 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.
– ThatAintWorking
Mar 23 '15 at 21:04
Great 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.
– ThatAintWorking
Mar 23 '15 at 21:04
31
31
", ".join(l)
- uses bad practice of using lowercase letter "L" as variable name. Let's don't teach programming newbies such examples in authoritative sources.– Nikolay Prokopyev
Feb 16 '17 at 13:30
", ".join(l)
- uses bad practice of using lowercase letter "L" as variable name. Let's don't teach programming newbies such examples in authoritative sources.– Nikolay Prokopyev
Feb 16 '17 at 13:30
7
7
plus1 for debuggers are useless, and don't scale worth a dime. Get your logging throughput up instead. And yes this was a well-written post. Turns out
__repr__
was what I needed for debugging. Thank you for your help.– personal_cloud
Sep 29 '17 at 15:43
plus1 for debuggers are useless, and don't scale worth a dime. Get your logging throughput up instead. And yes this was a well-written post. Turns out
__repr__
was what I needed for debugging. Thank you for your help.– personal_cloud
Sep 29 '17 at 15:43
3
3
your debugger folly aside, i learnt the %r and that's worth the vote anyway
– Mickey Perlstein
Dec 13 '18 at 9:21
your debugger folly aside, i learnt the %r and that's worth the vote anyway
– Mickey Perlstein
Dec 13 '18 at 9:21
|
show 1 more comment
My rule of thumb: __repr__
is for developers, __str__
is for customers.
add a comment |
My rule of thumb: __repr__
is for developers, __str__
is for customers.
add a comment |
My rule of thumb: __repr__
is for developers, __str__
is for customers.
My rule of thumb: __repr__
is for developers, __str__
is for customers.
answered Sep 17 '09 at 11:35
Ned BatchelderNed Batchelder
263k53447570
263k53447570
add a comment |
add a comment |
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 acceptable as input to __eval__
!
28
In my unit tests I always check thateval(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.
– Steven T. Snyder
Nov 15 '11 at 19:58
2
I always try to make sure that eithereval(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.
– abarnert
Sep 20 '14 at 5:34
plus1 for explaining that__str__
is implemented in terms of__repr__
. Seems to be something the other posts missed.
– personal_cloud
Sep 29 '17 at 15:45
Why 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.
– SuperGeo
Jan 26 '18 at 14:15
Just ran into an annoying bug related to the fact thateval(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.
– max
Jan 13 at 13:26
|
show 1 more comment
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 acceptable as input to __eval__
!
28
In my unit tests I always check thateval(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.
– Steven T. Snyder
Nov 15 '11 at 19:58
2
I always try to make sure that eithereval(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.
– abarnert
Sep 20 '14 at 5:34
plus1 for explaining that__str__
is implemented in terms of__repr__
. Seems to be something the other posts missed.
– personal_cloud
Sep 29 '17 at 15:45
Why 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.
– SuperGeo
Jan 26 '18 at 14:15
Just ran into an annoying bug related to the fact thateval(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.
– max
Jan 13 at 13:26
|
show 1 more comment
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 acceptable as input to __eval__
!
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 acceptable as input to __eval__
!
answered Sep 17 '09 at 4:49
Alex MartelliAlex Martelli
636k12910461284
636k12910461284
28
In my unit tests I always check thateval(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.
– Steven T. Snyder
Nov 15 '11 at 19:58
2
I always try to make sure that eithereval(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.
– abarnert
Sep 20 '14 at 5:34
plus1 for explaining that__str__
is implemented in terms of__repr__
. Seems to be something the other posts missed.
– personal_cloud
Sep 29 '17 at 15:45
Why 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.
– SuperGeo
Jan 26 '18 at 14:15
Just ran into an annoying bug related to the fact thateval(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.
– max
Jan 13 at 13:26
|
show 1 more comment
28
In my unit tests I always check thateval(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.
– Steven T. Snyder
Nov 15 '11 at 19:58
2
I always try to make sure that eithereval(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.
– abarnert
Sep 20 '14 at 5:34
plus1 for explaining that__str__
is implemented in terms of__repr__
. Seems to be something the other posts missed.
– personal_cloud
Sep 29 '17 at 15:45
Why 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.
– SuperGeo
Jan 26 '18 at 14:15
Just ran into an annoying bug related to the fact thateval(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.
– max
Jan 13 at 13:26
28
28
In my unit tests I always check that
eval(repr(foo))
evaluates to an object equal to foo
. 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.– Steven T. Snyder
Nov 15 '11 at 19:58
In my unit tests I always check that
eval(repr(foo))
evaluates to an object equal to foo
. 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.– Steven T. Snyder
Nov 15 '11 at 19:58
2
2
I always try to make sure that either
eval(repr(spam)) == spam
(at least in the right context), or eval(repr(spam))
raises a SyntaxError
. That way you avoid confusion. (And that's almost true for the builtins and most of the stdlib, except for, e.g., recursive lists, where a=; a.append(a); print(eval(repr(a)))
gives you [[Ellipses]]
…) Of course I don't do that to actually use eval(repr(spam))
, except as a sanity check in unit tests… but I do sometimes copy and paste repr(spam)
into an interactive session.– abarnert
Sep 20 '14 at 5:34
I always try to make sure that either
eval(repr(spam)) == spam
(at least in the right context), or eval(repr(spam))
raises a SyntaxError
. That way you avoid confusion. (And that's almost true for the builtins and most of the stdlib, except for, e.g., recursive lists, where a=; a.append(a); print(eval(repr(a)))
gives you [[Ellipses]]
…) Of course I don't do that to actually use eval(repr(spam))
, except as a sanity check in unit tests… but I do sometimes copy and paste repr(spam)
into an interactive session.– abarnert
Sep 20 '14 at 5:34
plus1 for explaining that
__str__
is implemented in terms of __repr__
. Seems to be something the other posts missed.– personal_cloud
Sep 29 '17 at 15:45
plus1 for explaining that
__str__
is implemented in terms of __repr__
. Seems to be something the other posts missed.– personal_cloud
Sep 29 '17 at 15:45
Why 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.– SuperGeo
Jan 26 '18 at 14:15
Why 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.– SuperGeo
Jan 26 '18 at 14:15
Just 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 on eval(repr(A.X))
. It's sad, but understandable. BTW, eval(str(A.X))
actually works, but of course only if class A
is in scope -- so it's probably not very useful.– max
Jan 13 at 13:26
Just 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 on eval(repr(A.X))
. It's sad, but understandable. BTW, eval(str(A.X))
actually works, but of course only if class A
is in scope -- so it's probably not very useful.– max
Jan 13 at 13:26
|
show 1 more comment
__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
add a comment |
__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
add a comment |
__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
__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
edited Aug 15 '12 at 19:40
Andrew Clark
148k17198257
148k17198257
answered Sep 17 '09 at 4:35
add a comment |
add a comment |
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 toeval()
, 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 withrepr(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,''
.
1
What is the meaning of printable string here? Can you explain it please?
– Vicrobot
Aug 19 '18 at 5:44
add a comment |
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 toeval()
, 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 withrepr(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,''
.
1
What is the meaning of printable string here? Can you explain it please?
– Vicrobot
Aug 19 '18 at 5:44
add a comment |
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 toeval()
, 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 withrepr(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,''
.
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 toeval()
, 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 withrepr(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,''
.
edited Oct 28 '13 at 0:23
deadly
1,1431223
1,1431223
answered Oct 25 '13 at 18:38
bitoffdevbitoffdev
2,1941913
2,1941913
1
What is the meaning of printable string here? Can you explain it please?
– Vicrobot
Aug 19 '18 at 5:44
add a comment |
1
What is the meaning of printable string here? Can you explain it please?
– Vicrobot
Aug 19 '18 at 5:44
1
1
What is the meaning of printable string here? Can you explain it please?
– Vicrobot
Aug 19 '18 at 5:44
What is the meaning of printable string here? Can you explain it please?
– Vicrobot
Aug 19 '18 at 5:44
add a comment |
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 (C Python source) 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__
(Python source). 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 = ", ".join(map(str, L))
s = "%s(%s)" % ('datetime.' + self.__class__.__name__, s)
if self._tzinfo is not None:
assert s[-1:] == ")"
s = s[:-1] + ", tzinfo=%r" % self._tzinfo + ")"
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 (Python source) 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.
Shouldn't it be something along the lines oftype(obj).__qualname__
?
– Solomon Ucko
Dec 1 '18 at 1:10
@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.
– Aaron Hall♦
Dec 1 '18 at 20:50
add a comment |
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 (C Python source) 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__
(Python source). 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 = ", ".join(map(str, L))
s = "%s(%s)" % ('datetime.' + self.__class__.__name__, s)
if self._tzinfo is not None:
assert s[-1:] == ")"
s = s[:-1] + ", tzinfo=%r" % self._tzinfo + ")"
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 (Python source) 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.
Shouldn't it be something along the lines oftype(obj).__qualname__
?
– Solomon Ucko
Dec 1 '18 at 1:10
@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.
– Aaron Hall♦
Dec 1 '18 at 20:50
add a comment |
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 (C Python source) 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__
(Python source). 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 = ", ".join(map(str, L))
s = "%s(%s)" % ('datetime.' + self.__class__.__name__, s)
if self._tzinfo is not None:
assert s[-1:] == ")"
s = s[:-1] + ", tzinfo=%r" % self._tzinfo + ")"
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 (Python source) 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.
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 (C Python source) 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__
(Python source). 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 = ", ".join(map(str, L))
s = "%s(%s)" % ('datetime.' + self.__class__.__name__, s)
if self._tzinfo is not None:
assert s[-1:] == ")"
s = s[:-1] + ", tzinfo=%r" % self._tzinfo + ")"
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 (Python source) 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.
edited Feb 25 '17 at 20:05
answered Jan 25 '15 at 2:01
Aaron Hall♦Aaron Hall
184k53309264
184k53309264
Shouldn't it be something along the lines oftype(obj).__qualname__
?
– Solomon Ucko
Dec 1 '18 at 1:10
@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.
– Aaron Hall♦
Dec 1 '18 at 20:50
add a comment |
Shouldn't it be something along the lines oftype(obj).__qualname__
?
– Solomon Ucko
Dec 1 '18 at 1:10
@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.
– Aaron Hall♦
Dec 1 '18 at 20:50
Shouldn't it be something along the lines of
type(obj).__qualname__
?– Solomon Ucko
Dec 1 '18 at 1:10
Shouldn't it be something along the lines of
type(obj).__qualname__
?– Solomon Ucko
Dec 1 '18 at 1:10
@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.
– Aaron Hall♦
Dec 1 '18 at 20:50
@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.
– Aaron Hall♦
Dec 1 '18 at 20:50
add a comment |
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 ...
.
add a comment |
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 ...
.
add a comment |
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 ...
.
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 ...
.
edited Jun 5 '18 at 7:47
David Augusto Villa
335
335
answered Sep 8 '16 at 3:27
Mangu Singh RajpurohitMangu Singh Rajpurohit
5,95223352
5,95223352
add a comment |
add a comment |
On page 358 of the book Python scripting for computational science by Hans Petter Langtangen, it clearly states that
- The
__repr__
aims at a complete string representation of the object; - The
__str__
is to return a nicely string for printing.
So, I prefer to understand them as
- repr = reproduce
- str = string (representation)
from the user point of view
although this is a misunderstanding i made when learning python.
A small but good example is also given on the same page as follows:
Example
In [38]: str('s')
Out[38]: 's'
In [39]: repr('s')
Out[39]: "'s'"
In [40]: eval(str('s'))
Traceback (most recent call last):
File "<ipython-input-40-abd46c0c43e7>", line 1, in <module>
eval(str('s'))
File "<string>", line 1, in <module>
NameError: name 's' is not defined
In [41]: eval(repr('s'))
Out[41]: 's'
It is at pg. #351.
– jiten
Dec 21 '18 at 13:10
add a comment |
On page 358 of the book Python scripting for computational science by Hans Petter Langtangen, it clearly states that
- The
__repr__
aims at a complete string representation of the object; - The
__str__
is to return a nicely string for printing.
So, I prefer to understand them as
- repr = reproduce
- str = string (representation)
from the user point of view
although this is a misunderstanding i made when learning python.
A small but good example is also given on the same page as follows:
Example
In [38]: str('s')
Out[38]: 's'
In [39]: repr('s')
Out[39]: "'s'"
In [40]: eval(str('s'))
Traceback (most recent call last):
File "<ipython-input-40-abd46c0c43e7>", line 1, in <module>
eval(str('s'))
File "<string>", line 1, in <module>
NameError: name 's' is not defined
In [41]: eval(repr('s'))
Out[41]: 's'
It is at pg. #351.
– jiten
Dec 21 '18 at 13:10
add a comment |
On page 358 of the book Python scripting for computational science by Hans Petter Langtangen, it clearly states that
- The
__repr__
aims at a complete string representation of the object; - The
__str__
is to return a nicely string for printing.
So, I prefer to understand them as
- repr = reproduce
- str = string (representation)
from the user point of view
although this is a misunderstanding i made when learning python.
A small but good example is also given on the same page as follows:
Example
In [38]: str('s')
Out[38]: 's'
In [39]: repr('s')
Out[39]: "'s'"
In [40]: eval(str('s'))
Traceback (most recent call last):
File "<ipython-input-40-abd46c0c43e7>", line 1, in <module>
eval(str('s'))
File "<string>", line 1, in <module>
NameError: name 's' is not defined
In [41]: eval(repr('s'))
Out[41]: 's'
On page 358 of the book Python scripting for computational science by Hans Petter Langtangen, it clearly states that
- The
__repr__
aims at a complete string representation of the object; - The
__str__
is to return a nicely string for printing.
So, I prefer to understand them as
- repr = reproduce
- str = string (representation)
from the user point of view
although this is a misunderstanding i made when learning python.
A small but good example is also given on the same page as follows:
Example
In [38]: str('s')
Out[38]: 's'
In [39]: repr('s')
Out[39]: "'s'"
In [40]: eval(str('s'))
Traceback (most recent call last):
File "<ipython-input-40-abd46c0c43e7>", line 1, in <module>
eval(str('s'))
File "<string>", line 1, in <module>
NameError: name 's' is not defined
In [41]: eval(repr('s'))
Out[41]: 's'
edited Jan 29 '18 at 5:47
0xc0de
4,80023666
4,80023666
answered May 21 '17 at 16:34
Yong YangYong Yang
48146
48146
It is at pg. #351.
– jiten
Dec 21 '18 at 13:10
add a comment |
It is at pg. #351.
– jiten
Dec 21 '18 at 13:10
It is at pg. #351.
– jiten
Dec 21 '18 at 13:10
It is at pg. #351.
– jiten
Dec 21 '18 at 13:10
add a comment |
In all honesty, eval(repr(obj))
is never used. If you find yourself using it, you should stop, because eval
is dangerous, and strings are a very inefficient way to serialize your objects (use pickle
instead).
Therefore, I would recommend setting __repr__ = __str__
. The reason is that str(list)
calls repr
on the elements (I consider this to be one of the biggest design flaws of Python that was not addressed by Python 3). An actual repr
will probably not be very helpful as the output of print [your, objects]
.
To qualify this, in my experience, the most useful use case of the repr
function is to put a string inside another string (using string formatting). This way, you don't have to worry about escaping quotes or anything. But note that there is no eval
happening here.
18
I think this misses the point. The use ofeval(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.
– jwg
Jun 6 '14 at 13:56
6
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.
– Luis Masuelli
Mar 1 '16 at 15:12
add a comment |
In all honesty, eval(repr(obj))
is never used. If you find yourself using it, you should stop, because eval
is dangerous, and strings are a very inefficient way to serialize your objects (use pickle
instead).
Therefore, I would recommend setting __repr__ = __str__
. The reason is that str(list)
calls repr
on the elements (I consider this to be one of the biggest design flaws of Python that was not addressed by Python 3). An actual repr
will probably not be very helpful as the output of print [your, objects]
.
To qualify this, in my experience, the most useful use case of the repr
function is to put a string inside another string (using string formatting). This way, you don't have to worry about escaping quotes or anything. But note that there is no eval
happening here.
18
I think this misses the point. The use ofeval(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.
– jwg
Jun 6 '14 at 13:56
6
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.
– Luis Masuelli
Mar 1 '16 at 15:12
add a comment |
In all honesty, eval(repr(obj))
is never used. If you find yourself using it, you should stop, because eval
is dangerous, and strings are a very inefficient way to serialize your objects (use pickle
instead).
Therefore, I would recommend setting __repr__ = __str__
. The reason is that str(list)
calls repr
on the elements (I consider this to be one of the biggest design flaws of Python that was not addressed by Python 3). An actual repr
will probably not be very helpful as the output of print [your, objects]
.
To qualify this, in my experience, the most useful use case of the repr
function is to put a string inside another string (using string formatting). This way, you don't have to worry about escaping quotes or anything. But note that there is no eval
happening here.
In all honesty, eval(repr(obj))
is never used. If you find yourself using it, you should stop, because eval
is dangerous, and strings are a very inefficient way to serialize your objects (use pickle
instead).
Therefore, I would recommend setting __repr__ = __str__
. The reason is that str(list)
calls repr
on the elements (I consider this to be one of the biggest design flaws of Python that was not addressed by Python 3). An actual repr
will probably not be very helpful as the output of print [your, objects]
.
To qualify this, in my experience, the most useful use case of the repr
function is to put a string inside another string (using string formatting). This way, you don't have to worry about escaping quotes or anything. But note that there is no eval
happening here.
edited Apr 14 '15 at 0:30
Aaron Hall♦
184k53309264
184k53309264
answered Nov 15 '12 at 10:39
asmeurerasmeurer
59.3k17114188
59.3k17114188
18
I think this misses the point. The use ofeval(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.
– jwg
Jun 6 '14 at 13:56
6
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.
– Luis Masuelli
Mar 1 '16 at 15:12
add a comment |
18
I think this misses the point. The use ofeval(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.
– jwg
Jun 6 '14 at 13:56
6
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.
– Luis Masuelli
Mar 1 '16 at 15:12
18
18
I 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.– jwg
Jun 6 '14 at 13:56
I 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.– jwg
Jun 6 '14 at 13:56
6
6
eval
is not inherently dangerous. Is not more dangerous than unlink
, 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.– Luis Masuelli
Mar 1 '16 at 15:12
eval
is not inherently dangerous. Is not more dangerous than unlink
, 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.– Luis Masuelli
Mar 1 '16 at 15:12
add a comment |
To put it simply:
__str__
is used in to show a string representation of your object to be read easily by others.
__repr__
is used to show a string representation of the object.
Let's say I want to create a Fraction
class where the string representation of a fraction is '(1/2)' and the object (Fraction class) is to be represented as 'Fraction (1,2)'
So we can create a simple Fraction class:
class Fraction:
def __init__(self, num, den):
self.__num = num
self.__den = den
def __str__(self):
return '(' + str(self.__num) + '/' + str(self.__den) + ')'
def __repr__(self):
return 'Fraction (' + str(self.__num) + ',' + str(self.__den) + ')'
f = Fraction(1,2)
print('I want to represent the Fraction STRING as ' + str(f)) # (1/2)
print('I want to represent the Fraction OBJECT as ', repr(f)) # Fraction (1,2)
add a comment |
To put it simply:
__str__
is used in to show a string representation of your object to be read easily by others.
__repr__
is used to show a string representation of the object.
Let's say I want to create a Fraction
class where the string representation of a fraction is '(1/2)' and the object (Fraction class) is to be represented as 'Fraction (1,2)'
So we can create a simple Fraction class:
class Fraction:
def __init__(self, num, den):
self.__num = num
self.__den = den
def __str__(self):
return '(' + str(self.__num) + '/' + str(self.__den) + ')'
def __repr__(self):
return 'Fraction (' + str(self.__num) + ',' + str(self.__den) + ')'
f = Fraction(1,2)
print('I want to represent the Fraction STRING as ' + str(f)) # (1/2)
print('I want to represent the Fraction OBJECT as ', repr(f)) # Fraction (1,2)
add a comment |
To put it simply:
__str__
is used in to show a string representation of your object to be read easily by others.
__repr__
is used to show a string representation of the object.
Let's say I want to create a Fraction
class where the string representation of a fraction is '(1/2)' and the object (Fraction class) is to be represented as 'Fraction (1,2)'
So we can create a simple Fraction class:
class Fraction:
def __init__(self, num, den):
self.__num = num
self.__den = den
def __str__(self):
return '(' + str(self.__num) + '/' + str(self.__den) + ')'
def __repr__(self):
return 'Fraction (' + str(self.__num) + ',' + str(self.__den) + ')'
f = Fraction(1,2)
print('I want to represent the Fraction STRING as ' + str(f)) # (1/2)
print('I want to represent the Fraction OBJECT as ', repr(f)) # Fraction (1,2)
To put it simply:
__str__
is used in to show a string representation of your object to be read easily by others.
__repr__
is used to show a string representation of the object.
Let's say I want to create a Fraction
class where the string representation of a fraction is '(1/2)' and the object (Fraction class) is to be represented as 'Fraction (1,2)'
So we can create a simple Fraction class:
class Fraction:
def __init__(self, num, den):
self.__num = num
self.__den = den
def __str__(self):
return '(' + str(self.__num) + '/' + str(self.__den) + ')'
def __repr__(self):
return 'Fraction (' + str(self.__num) + ',' + str(self.__den) + ')'
f = Fraction(1,2)
print('I want to represent the Fraction STRING as ' + str(f)) # (1/2)
print('I want to represent the Fraction OBJECT as ', repr(f)) # Fraction (1,2)
edited Jul 28 '16 at 4:08
Paulo Freitas
7,500136187
7,500136187
answered Jan 12 '16 at 2:53
Zer0Zer0
6871228
6871228
add a comment |
add a comment |
From http://pyref.infogami.com/__str__ by effbot:
__str__
"computes the "informal" string representation of an object. This differs from __repr__
in that it does not have to be a valid Python expression: a more convenient or concise representation may be used instead."
2
__repr__
is by no means required to return a vaild Python expression.
– Mad Physicist
Oct 20 '17 at 3:23
add a comment |
From http://pyref.infogami.com/__str__ by effbot:
__str__
"computes the "informal" string representation of an object. This differs from __repr__
in that it does not have to be a valid Python expression: a more convenient or concise representation may be used instead."
2
__repr__
is by no means required to return a vaild Python expression.
– Mad Physicist
Oct 20 '17 at 3:23
add a comment |
From http://pyref.infogami.com/__str__ by effbot:
__str__
"computes the "informal" string representation of an object. This differs from __repr__
in that it does not have to be a valid Python expression: a more convenient or concise representation may be used instead."
From http://pyref.infogami.com/__str__ by effbot:
__str__
"computes the "informal" string representation of an object. This differs from __repr__
in that it does not have to be a valid Python expression: a more convenient or concise representation may be used instead."
edited Oct 27 '17 at 22:09
Mad Physicist
38.7k1679112
38.7k1679112
answered Sep 17 '09 at 4:28
CasebashCasebash
49.5k73210321
49.5k73210321
2
__repr__
is by no means required to return a vaild Python expression.
– Mad Physicist
Oct 20 '17 at 3:23
add a comment |
2
__repr__
is by no means required to return a vaild Python expression.
– Mad Physicist
Oct 20 '17 at 3:23
2
2
__repr__
is by no means required to return a vaild Python expression.– Mad Physicist
Oct 20 '17 at 3:23
__repr__
is by no means required to return a vaild Python expression.– Mad Physicist
Oct 20 '17 at 3:23
add a comment |
One aspect that is missing in other answers. It's true that in general the pattern is:
- Goal of
__str__
: human-readable - Goal of
__repr__
: unambiguous, possibly machine-readable viaeval
Unfortunately, this differentiation is flawed, because the Python REPL and also IPython use __repr__
for printing objects in a REPL console (see related questions for Python and IPython). Thus, projects which are targeted for interactive console work (e.g., Numpy or Pandas) have started to ignore above rules and provide a human-readable __repr__
implementation instead.
1
I was wondering about this
– The Unfun Cat
Apr 15 '18 at 18:47
add a comment |
One aspect that is missing in other answers. It's true that in general the pattern is:
- Goal of
__str__
: human-readable - Goal of
__repr__
: unambiguous, possibly machine-readable viaeval
Unfortunately, this differentiation is flawed, because the Python REPL and also IPython use __repr__
for printing objects in a REPL console (see related questions for Python and IPython). Thus, projects which are targeted for interactive console work (e.g., Numpy or Pandas) have started to ignore above rules and provide a human-readable __repr__
implementation instead.
1
I was wondering about this
– The Unfun Cat
Apr 15 '18 at 18:47
add a comment |
One aspect that is missing in other answers. It's true that in general the pattern is:
- Goal of
__str__
: human-readable - Goal of
__repr__
: unambiguous, possibly machine-readable viaeval
Unfortunately, this differentiation is flawed, because the Python REPL and also IPython use __repr__
for printing objects in a REPL console (see related questions for Python and IPython). Thus, projects which are targeted for interactive console work (e.g., Numpy or Pandas) have started to ignore above rules and provide a human-readable __repr__
implementation instead.
One aspect that is missing in other answers. It's true that in general the pattern is:
- Goal of
__str__
: human-readable - Goal of
__repr__
: unambiguous, possibly machine-readable viaeval
Unfortunately, this differentiation is flawed, because the Python REPL and also IPython use __repr__
for printing objects in a REPL console (see related questions for Python and IPython). Thus, projects which are targeted for interactive console work (e.g., Numpy or Pandas) have started to ignore above rules and provide a human-readable __repr__
implementation instead.
answered May 26 '17 at 12:33
bluenote10bluenote10
9,01464793
9,01464793
1
I was wondering about this
– The Unfun Cat
Apr 15 '18 at 18:47
add a comment |
1
I was wondering about this
– The Unfun Cat
Apr 15 '18 at 18:47
1
1
I was wondering about this
– The Unfun Cat
Apr 15 '18 at 18:47
I was wondering about this
– The Unfun Cat
Apr 15 '18 at 18:47
add a comment |
str
- Creates a new string object from the given object.
repr
- Returns the canonical string representation of the object.
The differences:
str():
- makes object readable
- generates output for end-user
repr():
- needs code that reproduces object
- generates output for developer
add a comment |
str
- Creates a new string object from the given object.
repr
- Returns the canonical string representation of the object.
The differences:
str():
- makes object readable
- generates output for end-user
repr():
- needs code that reproduces object
- generates output for developer
add a comment |
str
- Creates a new string object from the given object.
repr
- Returns the canonical string representation of the object.
The differences:
str():
- makes object readable
- generates output for end-user
repr():
- needs code that reproduces object
- generates output for developer
str
- Creates a new string object from the given object.
repr
- Returns the canonical string representation of the object.
The differences:
str():
- makes object readable
- generates output for end-user
repr():
- needs code that reproduces object
- generates output for developer
answered Dec 4 '16 at 16:18
InconnuInconnu
3,77322134
3,77322134
add a comment |
add a comment |
"A basic requirement for a Python object is to provide usable
string representations of itself, one used for debugging and
logging, another for presentation to end users. That is why the
special methods __repr__ and __str__ exist in the data model."
From the book: Fluent Python
add a comment |
"A basic requirement for a Python object is to provide usable
string representations of itself, one used for debugging and
logging, another for presentation to end users. That is why the
special methods __repr__ and __str__ exist in the data model."
From the book: Fluent Python
add a comment |
"A basic requirement for a Python object is to provide usable
string representations of itself, one used for debugging and
logging, another for presentation to end users. That is why the
special methods __repr__ and __str__ exist in the data model."
From the book: Fluent Python
"A basic requirement for a Python object is to provide usable
string representations of itself, one used for debugging and
logging, another for presentation to end users. That is why the
special methods __repr__ and __str__ exist in the data model."
From the book: Fluent Python
answered Apr 4 '17 at 12:35
Ijaz Ahmad KhanIjaz Ahmad Khan
3,73121430
3,73121430
add a comment |
add a comment |
Excellent answers already cover the difference between __str__
and __repr__
, which for me boils down to the former being readable even by an end user, and the latter being as useful as possible to developers. Given that, I find that the default implementation of __repr__
often fails to achieve this goal because it omits information useful to developers.
For this reason, if I have a simple enough __str__
, I generally just try to get the best of both worlds with something like:
def __repr__(self):
return '{0} ({1})'.format(object.__repr__(self), str(self))
add a comment |
Excellent answers already cover the difference between __str__
and __repr__
, which for me boils down to the former being readable even by an end user, and the latter being as useful as possible to developers. Given that, I find that the default implementation of __repr__
often fails to achieve this goal because it omits information useful to developers.
For this reason, if I have a simple enough __str__
, I generally just try to get the best of both worlds with something like:
def __repr__(self):
return '{0} ({1})'.format(object.__repr__(self), str(self))
add a comment |
Excellent answers already cover the difference between __str__
and __repr__
, which for me boils down to the former being readable even by an end user, and the latter being as useful as possible to developers. Given that, I find that the default implementation of __repr__
often fails to achieve this goal because it omits information useful to developers.
For this reason, if I have a simple enough __str__
, I generally just try to get the best of both worlds with something like:
def __repr__(self):
return '{0} ({1})'.format(object.__repr__(self), str(self))
Excellent answers already cover the difference between __str__
and __repr__
, which for me boils down to the former being readable even by an end user, and the latter being as useful as possible to developers. Given that, I find that the default implementation of __repr__
often fails to achieve this goal because it omits information useful to developers.
For this reason, if I have a simple enough __str__
, I generally just try to get the best of both worlds with something like:
def __repr__(self):
return '{0} ({1})'.format(object.__repr__(self), str(self))
edited Apr 25 '18 at 19:35
coldspeed
141k25157245
141k25157245
answered Oct 29 '15 at 17:46
oromeorome
14.3k23112258
14.3k23112258
add a comment |
add a comment |
>>> print(decimal.Decimal(23) / decimal.Decimal("1.05"))
21.90476190476190476190476190
>>> decimal.Decimal(23) / decimal.Decimal("1.05")
Decimal('21.90476190476190476190476190')
When print() is called on the result of decimal.Decimal(23) / deci- mal.Decimal("1.05") the raw number is printed; this output is in string form which can be achieved with __str __(). If we simply enter the expression we get a decimal.Decimal output—this output is in representational form which can be achieved with __repr __(). All Python objects have two output forms. String form is designed to be human-readable. Representational form is designed to produce output that if fed to a Python interpreter would (when possible) re- produce the represented object
add a comment |
>>> print(decimal.Decimal(23) / decimal.Decimal("1.05"))
21.90476190476190476190476190
>>> decimal.Decimal(23) / decimal.Decimal("1.05")
Decimal('21.90476190476190476190476190')
When print() is called on the result of decimal.Decimal(23) / deci- mal.Decimal("1.05") the raw number is printed; this output is in string form which can be achieved with __str __(). If we simply enter the expression we get a decimal.Decimal output—this output is in representational form which can be achieved with __repr __(). All Python objects have two output forms. String form is designed to be human-readable. Representational form is designed to produce output that if fed to a Python interpreter would (when possible) re- produce the represented object
add a comment |
>>> print(decimal.Decimal(23) / decimal.Decimal("1.05"))
21.90476190476190476190476190
>>> decimal.Decimal(23) / decimal.Decimal("1.05")
Decimal('21.90476190476190476190476190')
When print() is called on the result of decimal.Decimal(23) / deci- mal.Decimal("1.05") the raw number is printed; this output is in string form which can be achieved with __str __(). If we simply enter the expression we get a decimal.Decimal output—this output is in representational form which can be achieved with __repr __(). All Python objects have two output forms. String form is designed to be human-readable. Representational form is designed to produce output that if fed to a Python interpreter would (when possible) re- produce the represented object
>>> print(decimal.Decimal(23) / decimal.Decimal("1.05"))
21.90476190476190476190476190
>>> decimal.Decimal(23) / decimal.Decimal("1.05")
Decimal('21.90476190476190476190476190')
When print() is called on the result of decimal.Decimal(23) / deci- mal.Decimal("1.05") the raw number is printed; this output is in string form which can be achieved with __str __(). If we simply enter the expression we get a decimal.Decimal output—this output is in representational form which can be achieved with __repr __(). All Python objects have two output forms. String form is designed to be human-readable. Representational form is designed to produce output that if fed to a Python interpreter would (when possible) re- produce the represented object
answered Jul 15 '15 at 10:30
BattleDrumBattleDrum
300313
300313
add a comment |
add a comment |
One important thing to keep in mind is that container's
__str__
uses contained objects'__repr__
.
>>> from datetime import datetime
>>> from decimal import Decimal
>>> print (Decimal('52'), datetime.now())
(Decimal('52'), datetime.datetime(2015, 11, 16, 10, 51, 26, 185000))
>>> str((Decimal('52'), datetime.now()))
"(Decimal('52'), datetime.datetime(2015, 11, 16, 10, 52, 22, 176000))"
Python favors 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.
It uses__repr__
when it (__str__
) is not defined! So, you are wrong.
– jiten
Dec 21 '18 at 13:48
add a comment |
One important thing to keep in mind is that container's
__str__
uses contained objects'__repr__
.
>>> from datetime import datetime
>>> from decimal import Decimal
>>> print (Decimal('52'), datetime.now())
(Decimal('52'), datetime.datetime(2015, 11, 16, 10, 51, 26, 185000))
>>> str((Decimal('52'), datetime.now()))
"(Decimal('52'), datetime.datetime(2015, 11, 16, 10, 52, 22, 176000))"
Python favors 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.
It uses__repr__
when it (__str__
) is not defined! So, you are wrong.
– jiten
Dec 21 '18 at 13:48
add a comment |
One important thing to keep in mind is that container's
__str__
uses contained objects'__repr__
.
>>> from datetime import datetime
>>> from decimal import Decimal
>>> print (Decimal('52'), datetime.now())
(Decimal('52'), datetime.datetime(2015, 11, 16, 10, 51, 26, 185000))
>>> str((Decimal('52'), datetime.now()))
"(Decimal('52'), datetime.datetime(2015, 11, 16, 10, 52, 22, 176000))"
Python favors 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.
One important thing to keep in mind is that container's
__str__
uses contained objects'__repr__
.
>>> from datetime import datetime
>>> from decimal import Decimal
>>> print (Decimal('52'), datetime.now())
(Decimal('52'), datetime.datetime(2015, 11, 16, 10, 51, 26, 185000))
>>> str((Decimal('52'), datetime.now()))
"(Decimal('52'), datetime.datetime(2015, 11, 16, 10, 52, 22, 176000))"
Python favors 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.
answered Nov 16 '15 at 3:02
zangwzangw
24.2k796116
24.2k796116
It uses__repr__
when it (__str__
) is not defined! So, you are wrong.
– jiten
Dec 21 '18 at 13:48
add a comment |
It uses__repr__
when it (__str__
) is not defined! So, you are wrong.
– jiten
Dec 21 '18 at 13:48
It uses
__repr__
when it (__str__
) is not defined! So, you are wrong.– jiten
Dec 21 '18 at 13:48
It uses
__repr__
when it (__str__
) is not defined! So, you are wrong.– jiten
Dec 21 '18 at 13:48
add a comment |
So much clearer
from blog
str is like toString. created so you can print the data
repr is like serialize, or pickle. How do i recreate this object if i need to do so using eval()
>>> import datetime
>>> now = datetime.datetime.now()
>>> str(now)
'2015-04-04 20:51:31.766862'
>>> repr(now)
'datetime.datetime(2015, 4, 4, 20, 51, 31, 766862)'
>>mydate = eval(repr(now))
add a comment |
So much clearer
from blog
str is like toString. created so you can print the data
repr is like serialize, or pickle. How do i recreate this object if i need to do so using eval()
>>> import datetime
>>> now = datetime.datetime.now()
>>> str(now)
'2015-04-04 20:51:31.766862'
>>> repr(now)
'datetime.datetime(2015, 4, 4, 20, 51, 31, 766862)'
>>mydate = eval(repr(now))
add a comment |
So much clearer
from blog
str is like toString. created so you can print the data
repr is like serialize, or pickle. How do i recreate this object if i need to do so using eval()
>>> import datetime
>>> now = datetime.datetime.now()
>>> str(now)
'2015-04-04 20:51:31.766862'
>>> repr(now)
'datetime.datetime(2015, 4, 4, 20, 51, 31, 766862)'
>>mydate = eval(repr(now))
So much clearer
from blog
str is like toString. created so you can print the data
repr is like serialize, or pickle. How do i recreate this object if i need to do so using eval()
>>> import datetime
>>> now = datetime.datetime.now()
>>> str(now)
'2015-04-04 20:51:31.766862'
>>> repr(now)
'datetime.datetime(2015, 4, 4, 20, 51, 31, 766862)'
>>mydate = eval(repr(now))
answered Apr 1 '18 at 13:32
Mickey PerlsteinMickey Perlstein
1,31321529
1,31321529
add a comment |
add a comment |
In a nutshell:
class Demo:
def __repr__(self):
return 'repr'
def __str__(self):
return 'str'
demo = Demo()
print(demo) # use __str__, output 'str' to stdout
s = str(demo) # __str__ is used, return 'str'
r = repr(demo) # __repr__ is used, return 'repr'
import logging
logger = logging.getLogger(logging.INFO)
logger.info(demo) # use __str__, output 'str' to stdout
from pprint import pprint, pformat
pprint(demo) # use __repr__, output 'repr' to stdout
result = pformat(demo) # use __repr__, result is string which value is 'str'
add a comment |
In a nutshell:
class Demo:
def __repr__(self):
return 'repr'
def __str__(self):
return 'str'
demo = Demo()
print(demo) # use __str__, output 'str' to stdout
s = str(demo) # __str__ is used, return 'str'
r = repr(demo) # __repr__ is used, return 'repr'
import logging
logger = logging.getLogger(logging.INFO)
logger.info(demo) # use __str__, output 'str' to stdout
from pprint import pprint, pformat
pprint(demo) # use __repr__, output 'repr' to stdout
result = pformat(demo) # use __repr__, result is string which value is 'str'
add a comment |
In a nutshell:
class Demo:
def __repr__(self):
return 'repr'
def __str__(self):
return 'str'
demo = Demo()
print(demo) # use __str__, output 'str' to stdout
s = str(demo) # __str__ is used, return 'str'
r = repr(demo) # __repr__ is used, return 'repr'
import logging
logger = logging.getLogger(logging.INFO)
logger.info(demo) # use __str__, output 'str' to stdout
from pprint import pprint, pformat
pprint(demo) # use __repr__, output 'repr' to stdout
result = pformat(demo) # use __repr__, result is string which value is 'str'
In a nutshell:
class Demo:
def __repr__(self):
return 'repr'
def __str__(self):
return 'str'
demo = Demo()
print(demo) # use __str__, output 'str' to stdout
s = str(demo) # __str__ is used, return 'str'
r = repr(demo) # __repr__ is used, return 'repr'
import logging
logger = logging.getLogger(logging.INFO)
logger.info(demo) # use __str__, output 'str' to stdout
from pprint import pprint, pformat
pprint(demo) # use __repr__, output 'repr' to stdout
result = pformat(demo) # use __repr__, result is string which value is 'str'
edited Apr 16 '18 at 9:28
BioGeek
12.2k1862109
12.2k1862109
answered Mar 23 '18 at 10:30
ShadowWalkerShadowWalker
5615
5615
add a comment |
add a comment |
Understand __str__
and __repr__
intuitively and permanently distinguish them at all.
__str__
return the string disguised body of a given object for readable of eyes__repr__
return the real flesh body of a given object (return itself) for unambiguity to identify.
See it in an example
In [30]: str(datetime.datetime.now())
Out[30]: '2017-12-07 15:41:14.002752'
Disguised in string form
As to __repr__
In [32]: datetime.datetime.now()
Out[32]: datetime.datetime(2017, 12, 7, 15, 43, 27, 297769)
Presence in real body which allows to be manipulated directly.
We can do arithmetic operation on __repr__
results conveniently.
In [33]: datetime.datetime.now()
Out[33]: datetime.datetime(2017, 12, 7, 15, 47, 9, 741521)
In [34]: datetime.datetime(2017, 12, 7, 15, 47, 9, 741521) - datetime.datetime(2
...: 017, 12, 7, 15, 43, 27, 297769)
Out[34]: datetime.timedelta(0, 222, 443752)
if apply the operation on __str__
In [35]: '2017-12-07 15:43:14.002752' - '2017-12-07 15:41:14.002752'
TypeError: unsupported operand type(s) for -: 'str' and 'str'
Returns nothing but error.
Another example.
In [36]: str('string_body')
Out[36]: 'string_body' # in string form
In [37]: repr('real_body')
Out[37]: "'real_body'" #its real body hide inside
Hope this help you build concrete grounds to explore more answers.
add a comment |
Understand __str__
and __repr__
intuitively and permanently distinguish them at all.
__str__
return the string disguised body of a given object for readable of eyes__repr__
return the real flesh body of a given object (return itself) for unambiguity to identify.
See it in an example
In [30]: str(datetime.datetime.now())
Out[30]: '2017-12-07 15:41:14.002752'
Disguised in string form
As to __repr__
In [32]: datetime.datetime.now()
Out[32]: datetime.datetime(2017, 12, 7, 15, 43, 27, 297769)
Presence in real body which allows to be manipulated directly.
We can do arithmetic operation on __repr__
results conveniently.
In [33]: datetime.datetime.now()
Out[33]: datetime.datetime(2017, 12, 7, 15, 47, 9, 741521)
In [34]: datetime.datetime(2017, 12, 7, 15, 47, 9, 741521) - datetime.datetime(2
...: 017, 12, 7, 15, 43, 27, 297769)
Out[34]: datetime.timedelta(0, 222, 443752)
if apply the operation on __str__
In [35]: '2017-12-07 15:43:14.002752' - '2017-12-07 15:41:14.002752'
TypeError: unsupported operand type(s) for -: 'str' and 'str'
Returns nothing but error.
Another example.
In [36]: str('string_body')
Out[36]: 'string_body' # in string form
In [37]: repr('real_body')
Out[37]: "'real_body'" #its real body hide inside
Hope this help you build concrete grounds to explore more answers.
add a comment |
Understand __str__
and __repr__
intuitively and permanently distinguish them at all.
__str__
return the string disguised body of a given object for readable of eyes__repr__
return the real flesh body of a given object (return itself) for unambiguity to identify.
See it in an example
In [30]: str(datetime.datetime.now())
Out[30]: '2017-12-07 15:41:14.002752'
Disguised in string form
As to __repr__
In [32]: datetime.datetime.now()
Out[32]: datetime.datetime(2017, 12, 7, 15, 43, 27, 297769)
Presence in real body which allows to be manipulated directly.
We can do arithmetic operation on __repr__
results conveniently.
In [33]: datetime.datetime.now()
Out[33]: datetime.datetime(2017, 12, 7, 15, 47, 9, 741521)
In [34]: datetime.datetime(2017, 12, 7, 15, 47, 9, 741521) - datetime.datetime(2
...: 017, 12, 7, 15, 43, 27, 297769)
Out[34]: datetime.timedelta(0, 222, 443752)
if apply the operation on __str__
In [35]: '2017-12-07 15:43:14.002752' - '2017-12-07 15:41:14.002752'
TypeError: unsupported operand type(s) for -: 'str' and 'str'
Returns nothing but error.
Another example.
In [36]: str('string_body')
Out[36]: 'string_body' # in string form
In [37]: repr('real_body')
Out[37]: "'real_body'" #its real body hide inside
Hope this help you build concrete grounds to explore more answers.
Understand __str__
and __repr__
intuitively and permanently distinguish them at all.
__str__
return the string disguised body of a given object for readable of eyes__repr__
return the real flesh body of a given object (return itself) for unambiguity to identify.
See it in an example
In [30]: str(datetime.datetime.now())
Out[30]: '2017-12-07 15:41:14.002752'
Disguised in string form
As to __repr__
In [32]: datetime.datetime.now()
Out[32]: datetime.datetime(2017, 12, 7, 15, 43, 27, 297769)
Presence in real body which allows to be manipulated directly.
We can do arithmetic operation on __repr__
results conveniently.
In [33]: datetime.datetime.now()
Out[33]: datetime.datetime(2017, 12, 7, 15, 47, 9, 741521)
In [34]: datetime.datetime(2017, 12, 7, 15, 47, 9, 741521) - datetime.datetime(2
...: 017, 12, 7, 15, 43, 27, 297769)
Out[34]: datetime.timedelta(0, 222, 443752)
if apply the operation on __str__
In [35]: '2017-12-07 15:43:14.002752' - '2017-12-07 15:41:14.002752'
TypeError: unsupported operand type(s) for -: 'str' and 'str'
Returns nothing but error.
Another example.
In [36]: str('string_body')
Out[36]: 'string_body' # in string form
In [37]: repr('real_body')
Out[37]: "'real_body'" #its real body hide inside
Hope this help you build concrete grounds to explore more answers.
edited Jan 2 '18 at 10:36
answered Dec 7 '17 at 8:03
JawSawJawSaw
4,85411939
4,85411939
add a comment |
add a comment |
__repr__
is used everywhere, except by print
and str
when a __str__
is defined
add a comment |
__repr__
is used everywhere, except by print
and str
when a __str__
is defined
add a comment |
__repr__
is used everywhere, except by print
and str
when a __str__
is defined
__repr__
is used everywhere, except by print
and str
when a __str__
is defined
answered May 8 '18 at 8:49
trthhrtztrthhrtz
5252623
5252623
add a comment |
add a comment |