how to use __str__ and __repr__?

Discussion in 'Python' started by Jim Newton, Jun 7, 2004.

  1. Jim Newton

    Jim Newton Guest

    hi all, does anyone know what print does if there is no __str__ method?
    i'm trying ot override the __repr__. If anyone can give me some advice
    it would be great to have.

    I have defined a lisp-like linked list class as a subclass of list.
    The __iter__ seems to work as i'd like, by traversing the links,
    and the __repr__ seems to work properly for somethings but not others.

    The basic idea is that a list such as [ 1, 2, 3, 4] is converted to
    [1, [2, [3, [4, nil]]], thus allowing me to push (cons) a new element
    non-destructively onto the beginning of the list; e.g.

    x = seq2pair( [ 3,4,5]) --> [ 3, [4, [5, nil]]]
    y = x.cons(2) --> [ 2, [3, [4, [5, nil]]]
    z = y.cons(1) --> [ 1, [ 2, [3, [4, [5, nil]]]]

    for elt in z: # iterates elt=1, elt=2, elt=3 ...
    pass

    I would love to know how to define the __repr__ or __str__
    method so that it is able to print everything the way print
    normally works, except that instances of my class gets printed
    special. I want to print [ 1, [ 2, [3, [4, [5, nil]]]]
    simple as a space seperated list. It works most of the time.
    --> ( 1 2 3 4 5)

    Another question is whether there is a way to promote an
    empty list [] to an instance of Pair?

    class Pair(list):

    def __iter__(self):
    while self:
    yield self.car()
    self = self.cdr()

    def __repr__(self):
    middle = " ".join( [ substr.__str__() for substr in self])
    return "( " + middle + " )"

    # x = (cons x l_y)
    # ==> x = l_y.cons(x)
    def cons(self, car):
    new = Pair()
    new.append(car)
    new.append(self)
    return new

    def car(self):
    if self:
    return self[0]
    return nil

    def cdr(self):
    if len(self)<2:
    return nil
    return self[1]

    nil = Pair()


    # [ 1, 2, 3] --> [1, [2, [3, nil]]]
    def seq2pair(seq):
    new = Pair()
    for index in xrange( len(seq), 0, -1):
    new = new.cons(seq[index - 1])
    return new

    mylist = seq2pair( [1,2,3,4,5])
    print mylist # correctly prints --> ( 1 2 3 4 5)


    mylist2 = seq2pair( [11.1, 21.1, 31.1, 41.1, mylist])
    print mylist2
    # correctly prints --> ( 11.1 21.1 31.1 41.1 ( 1 2 3 4 5 ) )

    class another:
    pass

    print another() # prints --> <__main__.another instance at 0x8132b64>

    # ????????????????????????????????????????
    print seq2pair( [ another(), another() ]) # FAILS
    # ????????????????????????????????????????

    Traceback (most recent call last):
    File "xyz.py", line 52, in ?
    print seq2pair( [ another(), another() ])
    File "xyz.py", line 13, in __repr__
    return "( " + " ".join( [ substr.__str__() for substr in self]) + " )"
    AttributeError: another instance has no attribute '__str__'
    Jim Newton, Jun 7, 2004
    #1
    1. Advertising

  2. Jim Newton

    Jim Newton Guest

    thanks for responding,
    i was expecting class().__str__()
    to evaluate to the string "<__main__.another instance at 0x8132b64>"
    because that what print does with class().
    but alas it does not.

    why does print class() not give me the same error as class().__str__()?
    that's what i do not understand.

    -jim


    Larry Bates wrote:
    > I don't understand what you are trying to do, but
    > the problem is that when you define class 'another'
    > the following line doesn't make sense:
    >
    > middle = " ".join( [ substr.__str__() for substr in self])
    >
    > The instance of another doesn't have a __str__ method
    > defined (e.g. it's an empty class). All of your other
    > tests have a class that does have a __str__ method
    > because it was inherited from the baseclass list.
    >
    > You could try:
    >
    > class another(list):
    > pass
    >
    > Larry Bates
    > Syscon, Inc.
    >
    > "Jim Newton" <> wrote in message
    > news:...
    >
    >>hi all, does anyone know what print does if there is no __str__ method?
    >>i'm trying ot override the __repr__. If anyone can give me some advice
    >>it would be great to have.
    >>
    >>I have defined a lisp-like linked list class as a subclass of list.
    >>The __iter__ seems to work as i'd like, by traversing the links,
    >>and the __repr__ seems to work properly for somethings but not others.
    >>
    >>The basic idea is that a list such as [ 1, 2, 3, 4] is converted to
    >>[1, [2, [3, [4, nil]]], thus allowing me to push (cons) a new element
    >>non-destructively onto the beginning of the list; e.g.
    >>
    >>x = seq2pair( [ 3,4,5]) --> [ 3, [4, [5, nil]]]
    >>y = x.cons(2) --> [ 2, [3, [4, [5, nil]]]
    >>z = y.cons(1) --> [ 1, [ 2, [3, [4, [5, nil]]]]
    >>
    >>for elt in z: # iterates elt=1, elt=2, elt=3 ...
    >> pass
    >>
    >>I would love to know how to define the __repr__ or __str__
    >>method so that it is able to print everything the way print
    >>normally works, except that instances of my class gets printed
    >>special. I want to print [ 1, [ 2, [3, [4, [5, nil]]]]
    >>simple as a space seperated list. It works most of the time.
    >>--> ( 1 2 3 4 5)
    >>
    >>Another question is whether there is a way to promote an
    >>empty list [] to an instance of Pair?
    >>
    >>class Pair(list):
    >>
    >> def __iter__(self):
    >> while self:
    >> yield self.car()
    >> self = self.cdr()
    >>
    >> def __repr__(self):
    >> middle = " ".join( [ substr.__str__() for substr in self])
    >> return "( " + middle + " )"
    >>
    >> # x = (cons x l_y)
    >> # ==> x = l_y.cons(x)
    >> def cons(self, car):
    >> new = Pair()
    >> new.append(car)
    >> new.append(self)
    >> return new
    >>
    >> def car(self):
    >> if self:
    >> return self[0]
    >> return nil
    >>
    >> def cdr(self):
    >> if len(self)<2:
    >> return nil
    >> return self[1]
    >>
    >>nil = Pair()
    >>
    >>
    >># [ 1, 2, 3] --> [1, [2, [3, nil]]]
    >>def seq2pair(seq):
    >> new = Pair()
    >> for index in xrange( len(seq), 0, -1):
    >> new = new.cons(seq[index - 1])
    >> return new
    >>
    >>mylist = seq2pair( [1,2,3,4,5])
    >>print mylist # correctly prints --> ( 1 2 3 4 5)
    >>
    >>
    >>mylist2 = seq2pair( [11.1, 21.1, 31.1, 41.1, mylist])
    >>print mylist2
    >># correctly prints --> ( 11.1 21.1 31.1 41.1 ( 1 2 3 4 5 ) )
    >>
    >>class another:
    >> pass
    >>
    >>print another() # prints --> <__main__.another instance at 0x8132b64>
    >>
    >># ????????????????????????????????????????
    >>print seq2pair( [ another(), another() ]) # FAILS
    >># ????????????????????????????????????????
    >>
    >>Traceback (most recent call last):
    >> File "xyz.py", line 52, in ?
    >> print seq2pair( [ another(), another() ])
    >> File "xyz.py", line 13, in __repr__
    >> return "( " + " ".join( [ substr.__str__() for substr in self]) +

    >
    > " )"
    >
    >>AttributeError: another instance has no attribute '__str__'
    >>

    >
    >
    >
    Jim Newton, Jun 7, 2004
    #2
    1. Advertising

  3. Jim Newton

    Jim Newton Guest

    i read that in the documenation. and i assumed from that that
    print another()
    actually prints the string returned from another().__str__()
    and thus __str__ must be being inherited from the superclass
    of another, but apparently print does something different.

    why does print another() actually print something rather than
    complaining that there is no __str__ defined?

    -jim


    Peter Hansen wrote:
    > Jim Newton wrote:
    >
    >> hi all, does anyone know what print does if there is no __str__ method?

    >
    >
    > From the documentation at http://docs.python.org/ref/customization.html :
    >
    > __repr__( self)
    >
    > Called by the repr() built-in function and by string conversions
    > (reverse quotes) to compute the ``official'' string representation of an
    > object. .... If a class defines __repr__() but not __str__(), then
    > __repr__() is also used when an ``informal'' string representation of
    > instances of that class is required.
    >
    > Does that help?
    Jim Newton, Jun 7, 2004
    #3
  4. Jim Newton

    Peter Hansen Guest

    Jim Newton wrote:

    > hi all, does anyone know what print does if there is no __str__ method?


    From the documentation at http://docs.python.org/ref/customization.html :

    __repr__( self)

    Called by the repr() built-in function and by string conversions
    (reverse quotes) to compute the ``official'' string representation of an
    object. .... If a class defines __repr__() but not __str__(), then
    __repr__() is also used when an ``informal'' string representation of
    instances of that class is required.

    Does that help?
    Peter Hansen, Jun 7, 2004
    #4
  5. Jim Newton

    Larry Bates Guest

    I don't understand what you are trying to do, but
    the problem is that when you define class 'another'
    the following line doesn't make sense:

    middle = " ".join( [ substr.__str__() for substr in self])

    The instance of another doesn't have a __str__ method
    defined (e.g. it's an empty class). All of your other
    tests have a class that does have a __str__ method
    because it was inherited from the baseclass list.

    You could try:

    class another(list):
    pass

    Larry Bates
    Syscon, Inc.

    "Jim Newton" <> wrote in message
    news:...
    > hi all, does anyone know what print does if there is no __str__ method?
    > i'm trying ot override the __repr__. If anyone can give me some advice
    > it would be great to have.
    >
    > I have defined a lisp-like linked list class as a subclass of list.
    > The __iter__ seems to work as i'd like, by traversing the links,
    > and the __repr__ seems to work properly for somethings but not others.
    >
    > The basic idea is that a list such as [ 1, 2, 3, 4] is converted to
    > [1, [2, [3, [4, nil]]], thus allowing me to push (cons) a new element
    > non-destructively onto the beginning of the list; e.g.
    >
    > x = seq2pair( [ 3,4,5]) --> [ 3, [4, [5, nil]]]
    > y = x.cons(2) --> [ 2, [3, [4, [5, nil]]]
    > z = y.cons(1) --> [ 1, [ 2, [3, [4, [5, nil]]]]
    >
    > for elt in z: # iterates elt=1, elt=2, elt=3 ...
    > pass
    >
    > I would love to know how to define the __repr__ or __str__
    > method so that it is able to print everything the way print
    > normally works, except that instances of my class gets printed
    > special. I want to print [ 1, [ 2, [3, [4, [5, nil]]]]
    > simple as a space seperated list. It works most of the time.
    > --> ( 1 2 3 4 5)
    >
    > Another question is whether there is a way to promote an
    > empty list [] to an instance of Pair?
    >
    > class Pair(list):
    >
    > def __iter__(self):
    > while self:
    > yield self.car()
    > self = self.cdr()
    >
    > def __repr__(self):
    > middle = " ".join( [ substr.__str__() for substr in self])
    > return "( " + middle + " )"
    >
    > # x = (cons x l_y)
    > # ==> x = l_y.cons(x)
    > def cons(self, car):
    > new = Pair()
    > new.append(car)
    > new.append(self)
    > return new
    >
    > def car(self):
    > if self:
    > return self[0]
    > return nil
    >
    > def cdr(self):
    > if len(self)<2:
    > return nil
    > return self[1]
    >
    > nil = Pair()
    >
    >
    > # [ 1, 2, 3] --> [1, [2, [3, nil]]]
    > def seq2pair(seq):
    > new = Pair()
    > for index in xrange( len(seq), 0, -1):
    > new = new.cons(seq[index - 1])
    > return new
    >
    > mylist = seq2pair( [1,2,3,4,5])
    > print mylist # correctly prints --> ( 1 2 3 4 5)
    >
    >
    > mylist2 = seq2pair( [11.1, 21.1, 31.1, 41.1, mylist])
    > print mylist2
    > # correctly prints --> ( 11.1 21.1 31.1 41.1 ( 1 2 3 4 5 ) )
    >
    > class another:
    > pass
    >
    > print another() # prints --> <__main__.another instance at 0x8132b64>
    >
    > # ????????????????????????????????????????
    > print seq2pair( [ another(), another() ]) # FAILS
    > # ????????????????????????????????????????
    >
    > Traceback (most recent call last):
    > File "xyz.py", line 52, in ?
    > print seq2pair( [ another(), another() ])
    > File "xyz.py", line 13, in __repr__
    > return "( " + " ".join( [ substr.__str__() for substr in self]) +

    " )"
    > AttributeError: another instance has no attribute '__str__'
    >
    Larry Bates, Jun 7, 2004
    #5
  6. Jim Newton wrote:

    > thanks for responding,
    > i was expecting class().__str__()
    > to evaluate to the string "<__main__.another instance at 0x8132b64>"
    > because that what print does with class().
    > but alas it does not.
    >
    > why does print class() not give me the same error as
    > class().__str__()?
    > that's what i do not understand.


    In the example you gave, your class is derived from list, so it uses
    list.__str__. It's doing exactly what an object-oriented system should
    do; defer to the base class. Why do you think that's wrong?

    --
    __ Erik Max Francis && && http://www.alcyone.com/max/
    / \ San Jose, CA, USA && 37 20 N 121 53 W && AIM erikmaxfrancis
    \__/ Whoever contends with the great sheds his own blood.
    -- Sa'di
    Erik Max Francis, Jun 8, 2004
    #6
  7. Jim Newton

    Peter Hansen Guest

    Jim Newton wrote:

    > i read that in the documenation. and i assumed from that that
    > print another()
    > actually prints the string returned from another().__str__()
    > and thus __str__ must be being inherited from the superclass
    > of another, but apparently print does something different.
    >
    > why does print another() actually print something rather than
    > complaining that there is no __str__ defined?


    I believe print basically calls str(obj) on the object, and
    str() is a builtin which (I believe) basically tries to call
    __str__() and if that is not defined, calls __repr__(). If
    __repr__ is not defined, it probably defers to a standard
    representation based on the id() of the object, which is
    always defined.

    Not sure what else you're trying to do (I haven't read your
    full post) but I believe this and some thought should answer
    for pretty much everything you're seeing.

    Note that you should probably never call __str__() directly,
    but call the str() builtin instead. Same for __repr__()
    versus the repr() builtin.

    -Peter
    Peter Hansen, Jun 8, 2004
    #7
  8. Jim Newton

    Jim Newton Guest

    if that is the case then why does the following fail

    class another:
    pass

    another.__str__()

    I would think that would return a string such as
    "<__main__.another instance at 0x8132b64>"
    but it does not seem to.


    Erik Max Francis wrote:
    > Jim Newton wrote:
    >
    >
    >>thanks for responding,
    >>i was expecting class().__str__()
    >>to evaluate to the string "<__main__.another instance at 0x8132b64>"
    >>because that what print does with class().
    >>but alas it does not.
    >>
    >>why does print class() not give me the same error as
    >>class().__str__()?
    >>that's what i do not understand.

    >
    >
    > In the example you gave, your class is derived from list, so it uses
    > list.__str__. It's doing exactly what an object-oriented system should
    > do; defer to the base class. Why do you think that's wrong?
    >
    Jim Newton, Jun 8, 2004
    #8
  9. Jim Newton

    Jim Newton Guest

    hmm, even when i change it to calling str() rather than __str__()
    it does not work.

    class another:
    pass

    print another() # works
    another().str() # does not work

    does anyone know why?

    -jim

    Peter Hansen wrote:
    > Jim Newton wrote:
    >
    >> i read that in the documenation. and i assumed from that that
    >> print another()
    >> actually prints the string returned from another().__str__()
    >> and thus __str__ must be being inherited from the superclass
    >> of another, but apparently print does something different.
    >>
    >> why does print another() actually print something rather than
    >> complaining that there is no __str__ defined?

    >
    >
    > I believe print basically calls str(obj) on the object, and
    > str() is a builtin which (I believe) basically tries to call
    > __str__() and if that is not defined, calls __repr__(). If
    > __repr__ is not defined, it probably defers to a standard
    > representation based on the id() of the object, which is
    > always defined.
    >
    > Not sure what else you're trying to do (I haven't read your
    > full post) but I believe this and some thought should answer
    > for pretty much everything you're seeing.
    >
    > Note that you should probably never call __str__() directly,
    > but call the str() builtin instead. Same for __repr__()
    > versus the repr() builtin.
    >
    > -Peter
    Jim Newton, Jun 8, 2004
    #9
  10. Jim Newton

    Carl Banks Guest

    Jim Newton wrote:
    > hmm, even when i change it to calling str() rather than __str__()
    > it does not work.
    >
    > class another:
    > pass
    >
    > print another() # works
    > another().str() # does not work
    >
    > does anyone know why?


    str is a function, not a method.

    str(another())


    --
    CARL BANKS http://www.aerojockey.com/software
    "If you believe in yourself, drink your school, stay on drugs, and
    don't do milk, you can get work."
    -- Parody of Mr. T from a Robert Smigel Cartoon
    Carl Banks, Jun 8, 2004
    #10
  11. Jim Newton

    Carl Banks Guest

    Carl Banks wrote:
    >
    >
    > Jim Newton wrote:
    >> hmm, even when i change it to calling str() rather than __str__()
    >> it does not work.
    >>
    >> class another:
    >> pass
    >>
    >> print another() # works
    >> another().str() # does not work
    >>
    >> does anyone know why?

    >
    > str is a function, not a method.


    (Ok, it's actually a type object.)


    --
    CARL BANKS http://www.aerojockey.com/software
    "If you believe in yourself, drink your school, stay on drugs, and
    don't do milk, you can get work."
    -- Parody of Mr. T from a Robert Smigel Cartoon
    Carl Banks, Jun 8, 2004
    #11
  12. Jim Newton wrote:

    > if that is the case then why does the following fail
    >
    > class another:
    > pass
    >
    > another.__str__()
    >
    > I would think that would return a string such as
    > "<__main__.another instance at 0x8132b64>"
    > but it does not seem to.


    Because __str__ is a special method which str defers to. If you want
    the str of anObject, call str(anObject). The object will then show you
    the string representation for that object. You shouldn't care whether
    or not it's got that behavior from defining a __str__ method, or whether
    it's gotten it from a parent class.

    --
    __ Erik Max Francis && && http://www.alcyone.com/max/
    / \ San Jose, CA, USA && 37 20 N 121 53 W && AIM erikmaxfrancis
    \__/ To endure what is unendurable is true endurance.
    -- (a Japanese proverb)
    Erik Max Francis, Jun 8, 2004
    #12
  13. Jim Newton

    Jim Newton Guest

    wow that works...

    def __repr__(self):
    middle = " ".join( [ str(substr) for substr in self])
    return "( " + middle + " )"

    thanks
    -jim


    Carl Banks wrote:
    > Carl Banks wrote:
    >
    >>
    >>Jim Newton wrote:
    >>
    >>>hmm, even when i change it to calling str() rather than __str__()
    >>>it does not work.
    >>>
    >>>class another:
    >>> pass
    >>>
    >>>print another() # works
    >>>another().str() # does not work
    >>>
    >>>does anyone know why?

    >>
    >>str is a function, not a method.

    >
    >
    > (Ok, it's actually a type object.)
    >
    >
    Jim Newton, Jun 8, 2004
    #13
  14. Jim Newton

    Jim Newton Guest

    promoting [] by superclass?

    wow that is great.

    now the other question:

    class Pair(list):
    ...

    how can i "cast", "promote" [] to class Pair?




    Erik Max Francis wrote:
    > Jim Newton wrote:
    >
    >
    >>if that is the case then why does the following fail
    >>
    >>class another:
    >> pass
    >>
    >>another.__str__()
    >>
    >>I would think that would return a string such as
    >>"<__main__.another instance at 0x8132b64>"
    >>but it does not seem to.

    >
    >
    > Because __str__ is a special method which str defers to. If you want
    > the str of anObject, call str(anObject). The object will then show you
    > the string representation for that object. You shouldn't care whether
    > or not it's got that behavior from defining a __str__ method, or whether
    > it's gotten it from a parent class.
    >
    Jim Newton, Jun 8, 2004
    #14
  15. Re: promoting [] by superclass?

    Jim Newton wrote:

    > wow that is great.
    >
    > now the other question:
    >
    > class Pair(list):
    > ...
    >
    > how can i "cast", "promote" [] to class Pair?


    You can't.

    --
    __ Erik Max Francis && && http://www.alcyone.com/max/
    / \ San Jose, CA, USA && 37 20 N 121 53 W && AIM erikmaxfrancis
    \__/ Sometimes there's no point in giving up.
    -- Louis Wu
    Erik Max Francis, Jun 8, 2004
    #15
  16. Jim Newton

    Peter Maas Guest

    Re: promoting [] by superclass?

    Erik Max Francis schrieb:
    > Jim Newton wrote:

    [...]
    >>class Pair(list):
    >> ...
    >>
    >>how can i "cast", "promote" [] to class Pair?

    >
    >
    > You can't.


    Perhaps I've got it wrong but Jim probably asks for overwriting
    the __getitem__ method.

    Mit freundlichen Gruessen,

    Peter Maas

    --
    -------------------------------------------------------------------
    Peter Maas, M+R Infosysteme, D-52070 Aachen, Hubert-Wienen-Str. 24
    Tel +49-241-93878-0 Fax +49-241-93878-20 eMail
    -------------------------------------------------------------------
    Peter Maas, Jun 9, 2004
    #16
    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. Dan Sommers
    Replies:
    3
    Views:
    301
    Serge Orlov
    Feb 19, 2005
  2. Jan Danielsson

    FAQ: __str__ vs __repr__

    Jan Danielsson, Jun 15, 2005, in forum: Python
    Replies:
    15
    Views:
    729
    Skip Montanaro
    Jun 21, 2005
  3. Neal Becker

    confused about __str__ vs. __repr__

    Neal Becker, Dec 18, 2008, in forum: Python
    Replies:
    1
    Views:
    252
    Diez B. Roggisch
    Dec 18, 2008
  4. Neal Becker

    Re: confused about __str__ vs. __repr__

    Neal Becker, Dec 18, 2008, in forum: Python
    Replies:
    3
    Views:
    341
    Steve Holden
    Dec 18, 2008
  5. Neal Becker

    Re: confused about __str__ vs. __repr__

    Neal Becker, Dec 18, 2008, in forum: Python
    Replies:
    12
    Views:
    625
    Carl Banks
    Dec 19, 2008
Loading...

Share This Page