Mailing List Archive

The purpose of the 'repr' builtin function
Hi!

Currently the wrapper classes UserList und UserString contain the
following method:

def __repr__(self): return repr(self.data)

I wonder about the following alternatives:

def __repr__(self):
return self.__class__.__name__ + "(" + repr(self.data) + ")"

or even more radical (here only for lists as an example):

def __repr__(self):
result = [self.__class__.__name__, "("]
for item in self.data:
result.append(repr(item))
result.append(", ")
result.append(")")
return "".join(result)

Just a thought which jumped into my mind during the recent discussion
about the purpose of the 'repr' function (float representation).

Regards, Peter
--
Peter Funk, Oldenburger Str.86, D-27777 Ganderkesee, Germany, Fax:+49 4222950260
office: +49 421 20419-0 (ArtCom GmbH, Grazer Str.8, D-28359 Bremen)
Re: The purpose of the 'repr' builtin function [ In reply to ]
> Currently the wrapper classes UserList und UserString contain the
> following method:
>
> def __repr__(self): return repr(self.data)
>
> I wonder about the following alternatives:
>
> def __repr__(self):
> return self.__class__.__name__ + "(" + repr(self.data) + ")"

Yes and no. It would make them behave less like their "theoretical"
base class, but you're right that it's better to be honest in repr().
Their str() could still look like self.data.

> or even more radical (here only for lists as an example):
>
> def __repr__(self):
> result = [self.__class__.__name__, "("]
> for item in self.data:
> result.append(repr(item))
> result.append(", ")
> result.append(")")
> return "".join(result)

What's the advantage of this? It seems designed to be faster, but I
doubt that it really is -- have you timed it? I'd go for simple --
how time-critical can repr() be...?

--Guido van Rossum (home page: http://www.python.org/~guido/)
Re: The purpose of the 'repr' builtin function [ In reply to ]
Hi!

[me:]
> > or even more radical (here only for lists as an example):
> >
> > def __repr__(self):
> > result = [self.__class__.__name__, "("]
> > for item in self.data:
> > result.append(repr(item))
> > result.append(", ")
> > result.append(")")
> > return "".join(result)

Guido van Rossum:
> What's the advantage of this? It seems designed to be faster, but I
> doubt that it really is -- have you timed it? I'd go for simple --
> how time-critical can repr() be...?

I feel sorry: The example above was nonsense. I confused 'str'
with 'repr' as I quickly hacked the function above in. I erroneously
thought 'repr(some_list)' calls 'str()' on the items. If I only had
checked more carefully before, I would have remembered that indeed
the opposite is true: Currently lists don't have '__str__' and so
fall back to 'repr' on the items when 'str([....])' is used.

All this is related to the recent discussion about the new annoying
behaviour of Python 1.6 when (mis?)used as a Desktop calculator:

Python 1.6a1 (#6, Apr 3 2000, 10:32:06) [GCC egcs-2.91.66 19990314/Linux (egcs-1.1.2 release)] on linux2
Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam
>>> print [0.1, 0.2]
[0.10000000000000001, 0.20000000000000001]
>>> print 0.1
0.1
>>> print (0.1, 0.2)
(0.10000000000000001, 0.20000000000000001)
>>> print (0.1, 0.2)[0]
0.1
>>> print (0.1, 0.2)[1]
0.2

So if default behaviour of the interactive interpreter would be changed
not to use 'repr()' for objects typed at the prompt (I believe Tim
Peters suggested that), this wouldn't help to make lists, tuples and
dictionaries containing floats more readable.

I don't know how to fix this, though. :-(

Regards, Peter
RE: The purpose of the 'repr' builtin function [ In reply to ]
[Peter Funk]
> ...
> So if default behaviour of the interactive interpreter would be changed
> not to use 'repr()' for objects typed at the prompt (I believe Tim
> Peters suggested that), this wouldn't help to make lists, tuples and
> dictionaries containing floats more readable.

Or lists, tuples and dicts of anything else either: that's what I'm getting
at when I keep saying containers should "pass str() down" to containees.
That it doesn't has frustrated me for years; newbies aren't bothered by it
because before 1.6 str == repr for almost all builtin types, and newbies (by
definition <wink>) don't have any classes of their own overriding __str__ or
__repr__. But I do, and their repr is rarely what I want to see in the
shell.

This is a different issue than (but related to) what the interactive prompt
should use by default to format expression results. They have one key
conundrum in common, though: if str() is simply passed down with no other
change, then e.g.

print str({"a:": "b, c", "a, b": "c"})
and (same thing in disguise)
print {"a:": "b, c", "a, b": "c"}

would display

{a:: b, c, a, b: c}

and that's darned unreadable. As far as I can tell, the only reason
str(container) invokes repr on the containees today is simply to get some
string quotes in output like this. That's fine so far as it goes, but leads
to miserably bloated displays for containees of many types *other* than the
builtin ones -- and even for string containees leads to embedded octal
escape sequences all over the place.

> I don't know how to fix this, though. :-(

Sure you do! And we look forward to your patch <wink>.