str behaviour

Igor V. Rafienko igorr at
Fri Mar 2 19:17:39 CET 2001

* Tim Peters


Thanks to everyone who replied.

> You're on the edge of a very deep pit. The builtin container types
> (lists, tuples, dicts) "pass repr down" regardless of whether str()
> or repr() is applied at the top level. I've been whining about that
> for years myself <wink>.

Argggh! This is silly -- why won't repr call repr and str call str
recursively? It seems like a very logical solution (consistent, imvho,
at least).

> The primary reason is maddeningly simple: it's for the benefit of
> contained strings. If str() "got passed down", then, e.g.,
>     d = {"colon": ":", "comma": ",", "' greeting": "I'm A"}
>     print d  # note that print implicitly applies str()
> would print
>    {' greeting: I'm A, comma: ,, colon: :}
> instead of today's
>    {"' greeting": "I'm A", 'comma': ',', 'colon': ':'}
> so it would be an unreadable mess.

Suits me fine :)

Jokes aside, if that were the case, I'd be more than happy to write

>>> print repr( d )

rather than 

>>> print d

and be very happy with the fact that repr did in fact call repr and
str did in fact call str. But maybe I am a very strange person...

BTW, since things are the way they are, could someone provide a
cleaner alternative to this snippet:

    # some code that might raise something nasty
    return MyError( "Something went wrong: (%s, %s)" %
	 	    ( sys.exc_info()[0], sys.exc_info()[1] ) )
# yrt

(yes, I can teach emacs to do that for me, but this is very painful on
the eyes of a reader).

All I wanted to do was to extract the value and type of the exception
raised in an elegant way:

return MyError( "Something went wrong: %s" % sys.exc_info()[:2] )
(which, obviously (gaah!), does not work as intended). A possible
solution is to use repr, of course (and define a repr for the class
that can be raise'd).


> Like most other issues involving repr-vs-str, it doesn't often bite
> so long as you stick to the builtin types. But once you write
> classes that implement their own notions of __str__ and __repr__, it
> seems that more often than not *neither* of them does what you want
> when instances end up in builtin containers.

I'd rather have str/repr call str/repr, than not. Am I missing
something obvious (apart from ugliness of strings, as you've
exemplified above)?

Besides, meat tends to run away when possible, or fights. Either
response presents behavioral challenges too complex for any existing
		-- Stuart Wilkinson, inventor of the "gastrobot"

More information about the Python-list mailing list