[Python-Dev] str(container) should call str(item), not repr(item)

Ondrej Certik ondrej at certik.cz
Mon Jul 28 10:28:34 CEST 2008


as discussed before here:


if you do:

>>> from decimal import Decimal
>>> a = Decimal(40)
>>> print a, a**2, a**3
40 1600 64000
>>> print [a, a**2, a**3]
[Decimal("40"), Decimal("1600"), Decimal("64000")]
>>> print {a: 3}
{Decimal("40"): 3}
>>> print {a: a**2}
{Decimal("40"): Decimal("1600")}

i.e. the str on list (and tuple and dict) calls repr() on the
elements, instead of str. This really seems to me like a bug. Because
if I wanted the repr() representation, I'd call repr() on the
list/tuple/dict. If I want a nice readable representation, I call
str(). That's the philosophy, no?

I understant there can be technical reasons why this cannot be made
into python 3.0, so why not 3.1? or 2.8?

If this cannot be made into python for some reason, how would you
suggest us we solve the following problem in sympy (symbolic
manipulation library):

>>> from sympy import Symbol, srepr
>>> x = Symbol("x")
>>> l = [x, x**2/2, x**3/3, x**4/4]
>>> str(l)
'[x, 1/2*x**2, 1/3*x**3, 1/4*x**4]'
>>> repr(l)
'[x, 1/2*x**2, 1/3*x**3, 1/4*x**4]'
>>> srepr(l)
"[Symbol('x'), Mul(Half(1, 2), Pow(Symbol('x'), Integer(2))),
Mul(Rational(1, 3), Pow(Symbol('x'), Integer(3))), Mul(Rational(1, 4),
Pow(Symbol('x'), Integer(4)))]"

As you can see, we currently have to hack our __repr__ to return the
same thing as __str__ so that things look nice in lists and
dictionaries. We provide the srepr() function that does what the
__repr__ should do instead. And as you can see, the result of srepr is
really not very readable, but it is easy to convert it back to a sympy
expression using eval. That's the purpose of repr(), no? However, you
cannot easily convert the str() back to an expression, because the
eval() doesn't know what "x" is.
One solution that we'll probably use is that we'll change our repr()
to the srepr output above, so str([x, x**2,...]) will not be pretty
and we'll use sys.displayhook to hook our own function into the
interactive session that overcomes this python behavior. This solves
the problem for interactive sessions, but it doesn't solve it if
people just call "print [x, x**2, ...]" inside their programs, for
example when debugging. Another option is to write a C extension
module that monkey patches the list class and changes the C pointer to
the (currently null) __str__ method to our own method. But I find it
very hackish and also it requires a C module.

I was discussing this with other people at EuroSciPy2008 and
everyone's first reaction that str(list) calls repr() on the elements
was that it's a bug. So was my reaction when I discovered that. So, I
think people find this highly unintuitive. So I just wanted to discuss
this more with core Python developers what you think about it and if
you also find this not very intuitive and if so, if there is any
chance to get this fixed.


More information about the Python-Dev mailing list