confused about __str__ vs. __repr__

J. Cliff Dyer jcd at sdf.lonestar.org
Thu Dec 18 15:56:11 EST 2008


On Thu, 2008-12-18 at 13:35 -0500, Neal Becker wrote:
> Mel wrote:
> 
> > Neal Becker wrote:
> > 
> >> 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.
> > 
> > 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




More information about the Python-list mailing list