Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

confused about __str__ vs. __repr__

23 views
Skip to first unread message

Neal Becker

unread,
Dec 18, 2008, 9:09:05 AM12/18/08
to pytho...@python.org
Reading some FAQ, I see that __str__ is "meant for human eyes".

But it seems that:
class X(object):
def __str__(self):
return "str"
def __repr__(self):
return "repr"

x = X()
d = {0 : x}
print d
{0: repr}

So if __str__ is "meant for human eyes", then why isn't print using it!

Tino Wildenhain

unread,
Dec 18, 2008, 9:14:34 AM12/18/08
to Neal Becker, pytho...@python.org

it is:

> print x
str

but dict just uses repr() for all its childs to print.

T.

Diez B. Roggisch

unread,
Dec 18, 2008, 9:20:48 AM12/18/08
to
Neal Becker wrote:

Because the __str__ of dict uses __repr__. Do a

print x

to see that print itself does use __str__.

BTW, could you configure your newsreader to not put the GMANE-group as
follow-up? NNTP doesn't work for that.

Diez

Neal Becker

unread,
Dec 18, 2008, 9:20:56 AM12/18/08
to pytho...@python.org
Tino Wildenhain wrote:

> Neal Becker wrote:
>> Reading some FAQ, I see that __str__ is "meant for human eyes".
>>
>> But it seems that:
>> class X(object):
>> def __str__(self):
>> return "str"
>> def __repr__(self):
>> return "repr"
>>
>> x = X()
>> d = {0 : x}
>> print d
>> {0: repr}
>>
>> So if __str__ is "meant for human eyes", then why isn't print using it!
>

> it is:
>
> > print x
> str
>
> but dict just uses repr() for all its childs to print.
>
> T.

That makes no sense to me. If I call 'print' on a container, why wouldn't it recursively print on the contained objects? Since print means call str, printing a container should recursively call str on the objects.

Tino Wildenhain

unread,
Dec 18, 2008, 9:36:01 AM12/18/08
to Neal Becker, pytho...@python.org
Neal Becker wrote:
...

>>> So if __str__ is "meant for human eyes", then why isn't print using it!
>> it is:
>>
>> > print x
>> str
>>
>> but dict just uses repr() for all its childs to print.
>>
>> T.
> That makes no sense to me. If I call 'print' on a container, why wouldn't it recursively print on the contained objects? Since print means call str, printing a container should recursively call str on the objects.

Every class is free on how to best implement __str__, you will find
the same behavior on tuple and list as well.

Maybe its discussable to change the implementation sensibly, best if you
would come with a proposal? Perhaps pprint.pprint is a starting point?

Regards
Tino

Neal Becker

unread,
Dec 18, 2008, 9:51:01 AM12/18/08
to pytho...@python.org
Tino Wildenhain wrote:

First, I'd like to know if there is a rationale for the current design. Am I correct in thinking this is a defect?

Jean-Paul Calderone

unread,
Dec 18, 2008, 10:10:54 AM12/18/08
to pytho...@python.org

There is a rationale. Consider:

>>> class strit(object):
... def __init__(self, it):
... self.it = it
... def __repr__(self):
... return str(self.it)
...

This will let us see what a dict.__str__ which called __str__ on the objects
in it would look like. So first, something simple:

>>> print str({strit("['foo']"): 'bar'})
{['foo']: 'bar'}
>>>

Mildly confusing - you can't use a list as a dict key! But it could be
worse:

>>> print str({strit("1: 2, 3"): 'bar'})
{1: 2, 3: 'bar'}
>>>

Wait - *how* many items are in that dictionary?

Hopefully that makes the rationale clear - when a human is looking at the
str of a dict (and a human is ostensibly the intended audience) - using
the __repr__ of the contained objects makes it easier for the human to
understand what's in the dict. Using __str__ would make it much harder
in many cases.

Jean-Paul

Diez B. Roggisch

unread,
Dec 18, 2008, 10:13:18 AM12/18/08
to
Neal Becker wrote:

I don't think so. First of all, there is no "generic" way of printing a
collection. And the current implementation tries to give an overview what
is contained in the collection, without trying to make it "fancy" - any
such thing needed to be hand-coded anyway.

Using repr for that is better suited, as for example string keys are printed
with quotes around them - making clear what they are, and not irritating
the user through potentially contained spaces or even things that look as
if they are python objects.

For example, if repr *wasn't* used,

{ "{foo=bar}" : "baz"}

would be printed

{{foo=bar} : baz}

Which is *not* what the dictionary actually contains!

The same goes for unicode-objects. They appear with their "funny" characters
as \xXX-codes - instead of bailing out on you with unicode-errors.

So, IMHO the current behavior is desired.

Diez

Neal Becker

unread,
Dec 18, 2008, 10:49:27 AM12/18/08
to pytho...@python.org
Diez B. Roggisch wrote:

So if I want to overload something in my custom class, so that I get a nice string whether it's printed directly, or as part of a container, what is the recommendation? Overload both __str__ and __repr__?


Diez B. Roggisch

unread,
Dec 18, 2008, 10:53:08 AM12/18/08
to
Neal Becker wrote:

Yep. And it's easy enough if you don't care about them being different..

def __repr__(self):
return str(self)


BTW, you newsreader still produces bogus follow-ups, which makes replying to
you unnerving.

Diez

Mikael Olofsson

unread,
Dec 18, 2008, 11:05:32 AM12/18/08
to
Diez B. Roggisch wrote:
> Yep. And it's easy enough if you don't care about them being different..
>
> def __repr__(self):
> return str(self)

If I ever wanted __str__ and __repr__ to return the same thing, I would
make them equal:

def __str__(self):
return 'whatever you want'
__repr__ = __str__

That makes it more obvious to me what's going on. As a bonus, it saves
one method call for every repr call.

/MiO

rdmu...@bitdance.com

unread,
Dec 18, 2008, 11:14:31 AM12/18/08
to pytho...@python.org
Quoth "Diez B. Roggisch" <de...@nospam.web.de>:

> Neal Becker wrote:
>
> > Tino Wildenhain wrote:
> >
> >> Neal Becker wrote:
> >> ...
> >>> That makes no sense to me. If I call 'print' on a container, why
> >>> wouldn't it recursively print on the contained objects? Since print
> >>> means call str, printing a container should recursively call str on the
> >>> objects.
[...]

> >> Every class is free on how to best implement __str__, you will find
> >> the same behavior on tuple and list as well.
> >>
> >> Maybe its discussable to change the implementation sensibly, best if you
> >> would come with a proposal? Perhaps pprint.pprint is a starting point?
> >>
> >> Regards
> >> Tino
> >
> > First, I'd like to know if there is a rationale for the current design.
> > Am I correct in thinking this is a defect?
>
> I don't think so. First of all, there is no "generic" way of printing a
> collection. And the current implementation tries to give an overview what
> is contained in the collection, without trying to make it "fancy" - any
> such thing needed to be hand-coded anyway.
>
> Using repr for that is better suited, as for example string keys are printed
> with quotes around them - making clear what they are, and not irritating
> the user through potentially contained spaces or even things that look as
> if they are python objects.
>
> For example, if repr *wasn't* used,
>
> { "{foo=bar}" : "baz"}
>
> would be printed
>
> {{foo=bar} : baz}
>
> Which is *not* what the dictionary actually contains!
>
> The same goes for unicode-objects. They appear with their "funny" characters
> as \xXX-codes - instead of bailing out on you with unicode-errors.

Note that this last is no longer true in Python 3.0. There, repr prints
into the current encoding of the output, and so you may get decode errors.
This is an accepted usability tradeoff, as it allows people using these
character sets (and who therefore will have terminals set to display
them!) to actually see the characters in their data. If you need the
old behavior you use 'ascii'.

--RDM

Mel

unread,
Dec 18, 2008, 11:57:08 AM12/18/08
to
Neal Becker wrote:

Basically because there are too many right ways to format the resulting
report. Space separated? Tab separated? One per line? Boxes around
them? As HTML definition lists? Creating a standard report form would
take a lot of work and wouldn't, finally, solve very many peoples'
problems.

Mel.

Neal Becker

unread,
Dec 18, 2008, 1:35:33 PM12/18/08
to pytho...@python.org
Mel wrote:

Thanks, but the question of how to format the container is different from how to format the primitive elements of the container. I was suggesting that printing an element of a container should be consistent with printing the element without the container, i.e.,

print [a]
should be consistent with
print a


J. Cliff Dyer

unread,
Dec 18, 2008, 3:56:11 PM12/18/08
to pytho...@python.org

On Thu, 2008-12-18 at 13:35 -0500, Neal Becker wrote:
> Thanks, but the question of how to format the container is different from how to format the primitive elements of the container. I was suggesting that printing an element of a container should be consistent with printing the element without the container, i.e.,
>
> print [a]
> should be consistent with
> print a
>
>

Well, first of all, an object is an object. Whether it is a container
or not is a matter of semantic convenience. And how an object prints
itself is up to that object and that object alone. If the object
chooses to recursively call __str__ on its elements, it is free to do
so, but since that causes ambiguity (as many people have pointed out),
python has (wisely) chosen to use repr instead. If I wanted to
implement a list-like class that doesn't show it's elements at all when
printed, but instead shows its length, I am free to do so.

For example:

>>> hl = HiddenList(1,2,3)
>>> hl
<HiddenList object: length=3>
>>> hl[1]
2

(Implementation of HiddenList left as an exercise for the reader.)

If you want to implement a list-like object that returns the str of its
elements, go right ahead, or implement a function that digs into
containers and creates its own list representation for them. But that's
not how python works by default, nor should it be, for reasons already
explained by others.


Cheers,
Cliff

Robert Kern

unread,
Dec 18, 2008, 4:27:17 PM12/18/08
to pytho...@python.org

Or just define __repr__(). str() falls back to __repr__() if __str__() is not
defined.

--
Robert Kern

"I have come to believe that the whole world is an enigma, a harmless enigma
that is made terrible by our own mad attempt to interpret it as though it had
an underlying truth."
-- Umberto Eco

Scott David Daniels

unread,
Dec 18, 2008, 4:29:44 PM12/18/08
to
J. Cliff Dyer wrote:
> ... how an object prints itself is up to that object and that object alone....

> If I wanted to implement a list-like class that doesn't show it's elements at
> all when printed, but instead shows its length, I am free to do so.
> For example:
>
>>>> hl = HiddenList(1,2,3)
>>>> hl
> <HiddenList object: length=3>
>>>> hl[1]
> 2
>
> (Implementation of HiddenList left as an exercise for the reader.)

And just so some of you who wonder how hard this implementation is:
(2.4.X, 2.5.X, 2.6.X):
class HiddenList(list):
def __repr__(self):
return '<%s object: length=%s>' % (
type(self).__name__, len(self))
(3.0):
class HiddenList(list):
def __repr__(self):
return '<{0} object: length={1}>'.format(
type(self).__name__, len(self))

--Scott David Daniels
Scott....@Acm.Org

Steve Holden

unread,
Dec 18, 2008, 4:37:45 PM12/18/08
to pytho...@python.org
Neal Becker wrote:
> Mel wrote:
>
> Thanks, but the question of how to format the container is different from how to format the primitive elements of the container. I was suggesting that printing an element of a container should be consistent with printing the element without the container, i.e.,
>
> print [a]
> should be consistent with
> print a
>
Indeed, but that only demonstrates that you have failed to take the
point of the more perspicacious replied to your query.

Python is trying to avoid throwing away useful information. The only
people who would want to see a representation of a data structure such
as a list are programmers: if you want to show a list of values to a
regular user you format it in some required way.

regards
Steve
--
Steve Holden +1 571 484 6266 +1 800 494 3119
Holden Web LLC http://www.holdenweb.com/

Gabriel Genellina

unread,
Dec 18, 2008, 7:11:27 PM12/18/08
to pytho...@python.org
En Thu, 18 Dec 2008 14:05:32 -0200, Mikael Olofsson <mik...@isy.liu.se>
escribió:

It's even easier to define only __repr__, __str__ defaults to it:

>>> class OnlyRepr(object):
... def __repr__(self): return "repr called"
...
>>> class OnlyStr(object):
... def __str__(self): return "str called"
...
>>> class Both(OnlyRepr, OnlyStr):
... pass
...
>>> r = OnlyRepr()
>>> s = OnlyStr()
>>> b = Both()
>>> print "only repr:", repr(r), str(r)
only repr: repr called repr called
>>> print "only str: ", repr(s), str(s)
only str: <__main__.OnlyStr object at 0x00BA10F0> str called
>>> print "both: ", repr(b), str(b)
both: repr called str called

--
Gabriel Genellina

Steven D'Aprano

unread,
Dec 18, 2008, 8:02:07 PM12/18/08
to
On Thu, 18 Dec 2008 10:49:27 -0500, Neal Becker wrote:

> So if I want to overload something in my custom class, so that I get a
> nice string whether it's printed directly, or as part of a container,
> what is the recommendation? Overload both __str__ and __repr__?

Either or both or neither, whatever you feel is best. Or create a pretty-
print method, and call that manually. I've done all of the above at times.

Remember though, that ideally you should be able to round-trip your
objects to strings and back again:

obj = MyClass(args)
eval(repr(obj)) == obj

should be true.

This isn't compulsory, and it isn't always possible, but unless you have
good reason to avoid it, you should aim for that behaviour.


BTW Neal, your posts aren't word wrapped. When I read your posts, I get
each paragraph as one extremely LONG line scrolling way out to the side.
That's against the Internet standards for both email and Usenet, so could
you please configure your client to word-wrap at (say) 70 characters?

--
Steven

Steven D'Aprano

unread,
Dec 18, 2008, 8:15:35 PM12/18/08
to
On Thu, 18 Dec 2008 22:11:27 -0200, Gabriel Genellina wrote:

> En Thu, 18 Dec 2008 14:05:32 -0200, Mikael Olofsson <mik...@isy.liu.se>
> escribió:

...


>> If I ever wanted __str__ and __repr__ to return the same thing, I would
>> make them equal:
>>
>> def __str__(self):
>> return 'whatever you want'
>> __repr__ = __str__
>>
>> That makes it more obvious to me what's going on. As a bonus, it saves
>> one method call for every repr call.
>
> It's even easier to define only __repr__, __str__ defaults to it:

Easier, yes, but less obvious. I can never remember whether __repr__
calls __str__ or __str__ calls __repr__ if one or the other is missing.
And it costs a failed method lookup.

The method lookup is a micro-optimization, and therefore not important,
but as far as I'm concerned the extra clarity of doing __repr__ = __str__
is valuable.


--
Steven

Neal Becker

unread,
Dec 18, 2008, 8:27:36 PM12/18/08
to pytho...@python.org
Steven D'Aprano wrote:

> BTW Neal, your posts aren't word wrapped. When I read your posts, I get
> each paragraph as one extremely LONG line scrolling way out to the side.
> That's against the Internet standards for both email and Usenet, so could
> you please configure your client to word-wrap at (say) 70 characters?
>

Sorry, it is configured to wrap @76, but it is beta software and perhaps is not working correctly? Odd, when I view my previous posts (knode/gmane) they look fine.

Russ P.

unread,
Dec 18, 2008, 11:40:43 PM12/18/08
to

I learned a while ago to just define __repr__, and let __str__ revert
to it by default. Then, when I print a list for debugging purposes, I
see something useful (as opposed to a type name and an address).

The only reason that I can think of to define __str__ is to get two
different representations. For example, sometimes I need both a one-
line output format and a multi-line option for more clarity or detail.
Then I use __repr__ for the one-liner and __str__ for the multi-liner.

Carl Banks

unread,
Dec 19, 2008, 12:20:31 AM12/19/08
to

I would say no.

__repr__ should be specific--something that when evaled yields an
equal object, if possible--about what the object is. Overloading
__repr__ to return an unspecific human-readable message is a mistake,
and will frustrate users who are debugging, logging, inspecting
objects at the interactive prompt.

Neal's problem seems to be with the behavior of dict's __str__ method,
which prints repr() of objects when he wants str(). That is intended
behavior, like it or not, so I would say the appropriate thing is not
use dict's default printed representation, and just write a custom
formating function for dicts.


Carl Banks

0 new messages