str() for containers

Discussion in 'Python' started by George Sakkis, Jun 16, 2004.

  1. Hi all,

    I find the string representation behaviour of builtin containers
    (tuples,lists,dicts) unintuitive in that they don't call recursively str()
    on their contents (e.g. as in Java) :

    ###########################################

    >>> class A(object):
    >>> def __str__(self): return "a"
    >>> print A()

    a
    >>> print [A()]

    [<__main__.A object at 0xa1a5c6c>]
    >>> print map(str,[A()])

    ['a']

    ###########################################

    It's even more cumbersome for containers of containers (e.g. lists of dicts,
    etc.). Of course one can (or should) encapsulate such stuctures in a class
    and define __str__ to behave as expected, but why not having it by default ?
    Is there a good reason for this ?

    George
     
    George Sakkis, Jun 16, 2004
    #1
    1. Advertising

  2. George Sakkis wrote:
    > I find the string representation behaviour of builtin containers
    > (tuples,lists,dicts) unintuitive in that they don't call recursively str()
    > on their contents (e.g. as in Java) :


    They use repr(), not str():

    >>> class Foo(object):

    .... def __repr__(self):
    .... return 'foo'
    ....
    >>> print Foo()

    foo
    >>> print [Foo()]

    [foo]
     
    Leif K-Brooks, Jun 16, 2004
    #2
    1. Advertising

  3. George Sakkis

    Donn Cave Guest

    In article <>,
    "George Sakkis" <> wrote:

    > I find the string representation behaviour of builtin containers
    > (tuples,lists,dicts) unintuitive in that they don't call recursively str()
    > on their contents (e.g. as in Java)


    Please find last week's answers to this question at
    http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&th=62e7a6469ac7b40b

    If you're still interested in further discussion of this
    point, you could present an account of Java's approach
    for the edification of those of us who don't know.

    Donn Cave,
     
    Donn Cave, Jun 16, 2004
    #3
  4. George Sakkis

    Dan Bishop Guest

    Donn Cave <> wrote in message news:<>...
    > In article <>,
    > "George Sakkis" <> wrote:
    >
    > > I find the string representation behaviour of builtin containers
    > > (tuples,lists,dicts) unintuitive in that they don't call recursively str()
    > > on their contents (e.g. as in Java)

    >
    > Please find last week's answers to this question at
    > http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&th=62e7a6469ac7b40b
    >
    > If you're still interested in further discussion of this
    > point, you could present an account of Java's approach
    > for the edification of those of us who don't know.


    All Java classes include a toString() method (defined in the root
    class java.lang.Object), which returns the string representation of
    that object. Each of the standard collection classes in java.util
    defines its toString() method to recursively call toString() on its
    elements.

    For example, the program

    import java.util.*;
    public class Foo {
    public static void main(String[] args) {
    List lst = new ArrayList();
    lst.add("a");
    lst.add("b");
    lst.add("c");
    System.out.println(lst);
    }
    }

    prints "[a, b, c]".

    (Btw, this reminds me of something I like about Python: There are
    literals for variable length arrays, so you don't have to write code
    like that.)

    The difference from Python's approach is that there isn't an
    equivalent to Python's str/repr distinction. Obviously, when there's
    only one string conversion method, you won't use the wrong one.

    The other difference is that the built-in array types don't have a
    meaningful toString() method, so

    public class Foo {
    public static void main(String[] args) {
    String[] arr = {"a", "b", "c"};
    System.out.println(arr);
    }
    }

    prints "[Ljava.lang.String;@df6ccd" (or something similar).
     
    Dan Bishop, Jun 18, 2004
    #4
  5. George Sakkis

    Dan Bishop Guest

    Donn Cave <> wrote in message news:<>...
    > In article <>,
    > "George Sakkis" <> wrote:
    >
    > > I find the string representation behaviour of builtin containers
    > > (tuples,lists,dicts) unintuitive in that they don't call recursively str()
    > > on their contents (e.g. as in Java)

    >
    > Please find last week's answers to this question at
    > http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&th=62e7a6469ac7b40b
    >
    > If you're still interested in further discussion of this
    > point, you could present an account of Java's approach
    > for the edification of those of us who don't know.


    All Java classes include a toString() method (defined in the root
    class java.lang.Object), which returns the string representation of
    that object. Each of the standard collection classes in java.util
    defines its toString() method to recursively call toString() on its
    elements.

    For example, the program

    import java.util.*;
    public class Foo {
    public static void main(String[] args) {
    List lst = new ArrayList();
    lst.add("a");
    lst.add("b");
    lst.add("c");
    System.out.println(lst);
    }
    }

    prints "[a, b, c]".

    (Btw, this reminds me of something I like about Python: There are
    literals for variable length arrays, so you don't have to write code
    like that.)

    The difference from Python's approach is that there isn't an
    equivalent to Python's str/repr distinction. Obviously, when there's
    only one string conversion method, you won't use the wrong one.

    The other difference is that the built-in array types don't have a
    meaningful toString() method, so

    public class Foo {
    public static void main(String[] args) {
    String[] arr = {"a", "b", "c"};
    System.out.println(arr);
    }
    }

    prints "[Ljava.lang.String;@df6ccd" (or something similar).
     
    Dan Bishop, Jun 18, 2004
    #5
  6. George Sakkis

    Donn Cave Guest

    In article <>,
    (Dan Bishop) wrote:

    > All Java classes include a toString() method (defined in the root
    > class java.lang.Object), which returns the string representation of
    > that object. Each of the standard collection classes in java.util
    > defines its toString() method to recursively call toString() on its
    > elements.
    >
    > For example, the program
    >
    > import java.util.*;
    > public class Foo {
    > public static void main(String[] args) {
    > List lst = new ArrayList();
    > lst.add("a");
    > lst.add("b");
    > lst.add("c");
    > System.out.println(lst);
    > }
    > }
    >
    > prints "[a, b, c]".


    OK, so it's ambiguous - you don't know from the result
    whether there are three elements, or two or one - if
    one of the elements has its own ", ".

    > (Btw, this reminds me of something I like about Python: There are
    > literals for variable length arrays, so you don't have to write code
    > like that.)
    >
    > The difference from Python's approach is that there isn't an
    > equivalent to Python's str/repr distinction. Obviously, when there's
    > only one string conversion method, you won't use the wrong one.


    It would be fun to apply that reasoning to arithmetic
    operators. Which one does Java support?

    > The other difference is that the built-in array types don't have a
    > meaningful toString() method, so
    >
    > public class Foo {
    > public static void main(String[] args) {
    > String[] arr = {"a", "b", "c"};
    > System.out.println(arr);
    > }
    > }
    >
    > prints "[Ljava.lang.String;@df6ccd" (or something similar).


    Ah, I can see how appealing this system would be.
    What elegance!

    Donn Cave,
     
    Donn Cave, Jun 18, 2004
    #6
  7. George Sakkis

    Dan Bishop Guest

    Donn Cave <> wrote in message news:<>...
    > In article <>,
    > (Dan Bishop) wrote:
    >
    > > All Java classes include a toString() method (defined in the root
    > > class java.lang.Object), which returns the string representation of
    > > that object...[big snip]
    > > The difference from Python's approach is that there isn't an
    > > equivalent to Python's str/repr distinction. Obviously, when there's
    > > only one string conversion method, you won't use the wrong one.

    >
    > It would be fun to apply that reasoning to arithmetic
    > operators. Which one does Java support?


    toString() usually behaves more like Python's str than repr. An
    exception is Double.toString, which returns 16 signifcant digits.

    Jython uses toString() to implement both __str__ and __repr__ for Java
    classes.
     
    Dan Bishop, Jun 19, 2004
    #7
  8. George Sakkis

    John Roth Guest

    "George Sakkis" <> wrote in message
    news:...
    > Hi all,
    >
    > I find the string representation behaviour of builtin containers
    > (tuples,lists,dicts) unintuitive in that they don't call recursively str()
    > on their contents (e.g. as in Java) :


    > It's even more cumbersome for containers of containers (e.g. lists of

    dicts,
    > etc.). Of course one can (or should) encapsulate such stuctures in a class
    > and define __str__ to behave as expected, but why not having it by default

    ?
    > Is there a good reason for this ?


    I don't think there's a ***good*** reason. The root of
    the issue is that the str() / repr() distinction is too simplistic
    for containers. The output of str() is supposed to be human
    readable, and the output of repr() is supposed to be able
    to round-trip through exec/eval (which is not always possible,
    but should be maintained if it is.)

    Human readable output from a container, however, needs
    to be very clear on the distinction between the container
    and the objects that are contained. It isn't always obvious
    whether using str() or repr() on the contained object is the
    best policy, and in some cases I suspect that something
    different from either would be helpful.

    The only clean solution I can see is to provide a third built-in
    that provides the "right" output when a container class needs
    to turn an object into a string. However, someone else
    is going to have to do the work of writing up the use
    cases and the PEP - I don't care enough.

    John Roth
    >
    > George
    >
    >
     
    John Roth, Jun 19, 2004
    #8
  9. On Sat, 19 Jun 2004 08:41:56 -0400, John Roth wrote:

    > The only clean solution I can see is to provide a third built-in
    > that provides the "right" output when a container class needs
    > to turn an object into a string.


    What is the right thing e.g. for strings?

    --
    __("< Marcin Kowalczyk
    \__/
    ^^ http://qrnik.knm.org.pl/~qrczak/
     
    Marcin 'Qrczak' Kowalczyk, Jun 19, 2004
    #9
  10. George Sakkis

    Peter Hansen Guest

    Marcin 'Qrczak' Kowalczyk wrote:

    > On Sat, 19 Jun 2004 08:41:56 -0400, John Roth wrote:
    >
    >
    >>The only clean solution I can see is to provide a third built-in
    >>that provides the "right" output when a container class needs
    >>to turn an object into a string.

    >
    >
    > What is the right thing e.g. for strings?


    Exactly. ;-)
     
    Peter Hansen, Jun 19, 2004
    #10
  11. John Roth wrote:
    > "George Sakkis" <> wrote in message
    >>I find the string representation behaviour of builtin containers
    >>(tuples,lists,dicts) unintuitive in that they don't call recursively str()
    >>on their contents (e.g. as in Java) :

    > The only clean solution I can see is to provide a third built-in
    > that provides the "right" output when a container class needs
    > to turn an object into a string. However, someone else
    > is going to have to do the work of writing up the use
    > cases and the PEP - I don't care enough.


    For str of a container, I suggest using repr for strings in the
    container and str for everything else.
     
    Edward C. Jones, Jun 19, 2004
    #11
  12. George Sakkis

    Donn Cave Guest

    Quoth "John Roth" <>:
    ....
    | I don't think there's a ***good*** reason. The root of
    | the issue is that the str() / repr() distinction is too simplistic
    | for containers. The output of str() is supposed to be human
    | readable, and the output of repr() is supposed to be able
    | to round-trip through exec/eval (which is not always possible,
    | but should be maintained if it is.)

    That's one way to look at it, but it's a perspective that will
    always leave you dissatisfied with both str and repr.

    Not only is repr-as-marshal not always possible, it's very widely
    not implemented even when it could be, and anyone who relies on
    this feature is asking for trouble. Human readable is as vacuous
    an expectation as there could be for what str does, so it's hard
    to say for sure you'll be disappointed there, but then it's just
    impossible to imagine any solid basis for saying whether a value
    is going to be human readable. I've seen what the documentation
    says, and there has been plenty of discussion about this.

    The way I see it, __str__ is about conversion to string data. It
    really applies to only those objects that can naturally be converted
    to a string. If lists had a __str__ function, then str(list) would
    be the inverse of list(str), but since that would raise all kinds
    of questions about what to do with lists containing other things
    besides strings of length 1, there is no __str__ function. Instead,
    str(list) calls __repr__.

    Repr renders the object as a string. Not just the object's value
    in a computational sense, so to speak, but the object implementation.
    So it's typically more interesting to a programmer, than the program's
    user. That could be seen as a human readability issue, but it puts
    the point into better perspective - what's the user-oriented value
    of a list as string? There isn't one.

    Donn Cave,
     
    Donn Cave, Jun 20, 2004
    #12
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. David
    Replies:
    2
    Views:
    502
    Thomas G. Marshall
    Aug 3, 2003
  2. Trevor

    sizeof(str) or sizeof(str) - 1 ?

    Trevor, Apr 3, 2004, in forum: C Programming
    Replies:
    9
    Views:
    660
    CBFalconer
    Apr 10, 2004
  3. Sullivan WxPyQtKinter

    It is fun.the result of str.lower(str())

    Sullivan WxPyQtKinter, Mar 7, 2006, in forum: Python
    Replies:
    5
    Views:
    354
    Tim Roberts
    Mar 9, 2006
  4. Replies:
    7
    Views:
    574
    Pete Becker
    Jan 25, 2008
  5. Sebastian Mach
    Replies:
    5
    Views:
    340
Loading...

Share This Page