# how to use __str__ and __repr__?

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

1. ### Jim NewtonGuest

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. ### Jim NewtonGuest

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

3. ### Jim NewtonGuest

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
4. ### Peter HansenGuest

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
5. ### Larry BatesGuest

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
6. ### Erik Max FrancisGuest

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
7. ### Peter HansenGuest

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
8. ### Jim NewtonGuest

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
9. ### Jim NewtonGuest

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
10. ### Carl BanksGuest

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
11. ### Carl BanksGuest

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
12. ### Erik Max FrancisGuest

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
13. ### Jim NewtonGuest

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
14. ### Jim NewtonGuest

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
15. ### Erik Max FrancisGuest

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
16. ### Peter MaasGuest

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