469,599 Members | 2,897 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,599 developers. It's quick & easy.

how to use __str__ and __repr__?

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__'

Jul 18 '05 #1
15 5760
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?
Jul 18 '05 #2
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" <ji***@rdrop.com> wrote in message
news:2i************@uni-berlin.de...
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__'

Jul 18 '05 #3
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" <ji***@rdrop.com> wrote in message
news:2i************@uni-berlin.de...
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__'



Jul 18 '05 #4
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?


Jul 18 '05 #5
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 && ma*@alcyone.com && 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
Jul 18 '05 #6
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
Jul 18 '05 #7
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?


Jul 18 '05 #8
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


Jul 18 '05 #9
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
Jul 18 '05 #10
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
Jul 18 '05 #11
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 && ma*@alcyone.com && 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)
Jul 18 '05 #12
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.)


Jul 18 '05 #13
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.


Jul 18 '05 #14
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 && ma*@alcyone.com && 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
Jul 18 '05 #15
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 pe********@mplusr.de
-------------------------------------------------------------------
Jul 18 '05 #16

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

15 posts views Thread by Jan Danielsson | last post: by
7 posts views Thread by Jeffrey E. Forcier | last post: by
1 post views Thread by Edward C. Jones | last post: by
5 posts views Thread by Mike Krell | last post: by
6 posts views Thread by [david] | last post: by
5 posts views Thread by Konstantinos Pachopoulos | last post: by
reply views Thread by suresh191 | last post: by
4 posts views Thread by guiromero | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.