[Tutor] help with __str__

Danny Yoo dyoo at hkn.eecs.berkeley.edu
Fri Sep 3 00:07:28 CEST 2004



On Thu, 2 Sep 2004, Ron A wrote:

> This is from the book "Python Programming for the absolute beginner"
> slightly modified. It's concantenating rank and suit each time you
> create a new card and it seems to be doing it without having to use
> print card each time. How is the str method being used without using
> print? I'm really getting confused now.


Hi Ron,

The '__str__' method of a method does fire off when we print out a
thing... but it also fires off if we call the str() "string conversion" on
something.


For example:

###
>>> class TestStr:
...     def __str__(self):
...         print "*** DEBUG: __str__ is firing off!***"
...         return "TestStr instance"
...
>>> t = TestStr()
>>> print t
*** DEBUG: __str__ is firing off!***
TestStr instance
>>> value = str(t)
*** DEBUG: __str__ is firing off!***
>>>
###

Does this make sense?  __str__() is used by both Python's "print"
statement and the 'str()' builtin function, and your code is calling str()
on things.


We'd use str() if we want to get at the string value, but not necessarily
print out to screen.  For example, there are other things we can do to a
string value besides print it out directly:

###
>>> str(t) * 3
*** DEBUG: __str__ is firing off!***
'TestStr instanceTestStr instanceTestStr instance'
>>> len(str(t))
*** DEBUG: __str__ is firing off!***
16
###




One thing to realize is that 'print' itself does not give us a value.
It's something that works as a "side-effect": we see the thing that's
being printed, but otherwise, printing doesn't have a "value".  Here are
things that have values:

###
>>> 3 * 4
12
>>> 'ha' * 7
'hahahahahahaha'
###

These things are "expressions": they're calculations that result in a new
value.  We usually try to write our functions so that they return values.

###
>>> def square(x):
...     return x * x
...
>>> result = square(42)
>>> result
1764
###


'print' is different: it just prints to screen, but has no real value:

###
>>> def printSquare(x):
...     print x * x
...
>>> result = printSquare(42)
1764
>>> print result
None
###

We'd say that printSquare() has a "side-effect" of displaying the square
of a number on screen, but doesn't give back a useful value to us.
That's what 'None' is about.


The main different between the two here is that square() can easily be
used in some larger computation, but printSquare() can't:

###
>>> (square(3) + square(4)) ** 0.5
5.0
>>> (printSquare(3) + printSquare(4)) ** 0.5
9
16
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: unsupported operand type(s) for +: 'NoneType' and 'NoneType'
###


So that's why all of the functions in your program try not to just "print"
their computation: rather, they actually try to "return" the value to the
caller.  Most people try to get their functions to 'return' values because
such functions often end up being more useful than ones that only print to
screen.



If you have more questions, please feel free to ask.  Good luck!



More information about the Tutor mailing list