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.
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 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.
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?
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
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
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__?
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
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
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
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.
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
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
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
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/
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
> 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
> 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
> 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.
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.
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