[Tutor] Class instance understanding = None

Andre Engels andreengels at gmail.com
Fri Feb 27 09:00:39 CET 2009


On Fri, Feb 27, 2009 at 6:06 AM, David <david at abbottdavid.com> wrote:
> Hi Everyone,
> I go through the archived [Tutor] mail list to find programs others have
> tried to do. I found one that would keep track of a petty cash fund. please
> point out my misunderstanding.
> Here is what I started with;
> <code>
> #!/usr/bin/python
>
> from reportlab.lib.normalDate import ND
> #import cPickle as p
> #import pprint
>
> today = ND()
>
> class Account:
>    def __init__(self, initial):
>        self.balance = initial
>    def deposit(self, amt):
>        self.balance = self.balance + amt
>    def withdraw(self, amt):
>        self.balance = self.balance - amt
>    def getbalance(self):
>        return self.balance
> print 'The current date is: ', today.formatUS()
>
>
> data = float('100.00')
> a = Account(data)
> p = a.getbalance()
> print 'balance = ', p
> remove_data = float('50.00')
> w = a.withdraw(remove_data)
> print "withdraw = ", w
> add_data = float('50.00')
> add = a.deposit(add_data)
> print "deposit = ", add
> </code>
>
> results;
> The current date is:  02/27/09
> balance =  100.0
> withdraw =  None
> deposit =  None
>
> expected results;
> The current date is:  02/27/09
> balance =  100.0
> withdraw =  50.0
> deposit =  100.0

A method only returns a value if you do so explicitly, that is, end it with

return value

That's what happens in getbalance:

return self.balance

deposit and withdraw however do not return a value. If, like you do,
you still try to extract their return value, it gives None.

There are two ways to resolve this. The first gets closer to what you
are trying to do, but is considered less proper programming, because
it mixes functions of methods. In it, you add the returns to the
methods:

class Account:
  def __init__(self, initial):
      self.balance = initial
  def deposit(self, amt):
      self.balance = self.balance + amt
      return self.balance
  def withdraw(self, amt):
      self.balance = self.balance - amt
      return self.balance
  def getbalance(self):
      return self.balance

The more preferable method is to leave the class alone, and call
getbalance by hand:

data = float('100.00')
a = Account(data)
p = a.getbalance()
print 'balance = ', p
remove_data = float('50.00')
a.withdraw(remove_data)
w = a.getbalance()
print "withdraw = ", w
add_data = float('50.00')
a.deposit(add_data)
add = a.getbalance()
print "deposit = ", add

Some other things:
1. data = float('100.00') is unnecessarily clumsy - you can specify
floats directly without creating a string first by doing data = 100.0
2. You are creating a lot of variables only to use them for the one
and only time on the next line. That's not necessarily bad, it
sometimes improves readability especially if a lot is being done
(which can then be split up in more readable parts), but doing it this
much mostly causes your coding to look more complicated than it
actually is. I would either prefer something like this:

data = 100.0
remove_data = 50.0
add_data = 50.0        # first all input-like elements, so I know
where to go when I want to change something trivial
a = Account(data)
print 'balance = ',a.getbalance()
a.withdraw(remove_data)
print 'balance after withdraw = ',a.getbalance()
a.deposit(add_data)
print 'balance after deposit = ',a.getbalance()

doing away with p, w and add, or the even shorter variant where data,
remove_data and add_data are also removed:

a = Account(100.0)
print 'balance = ',a.getbalance()
a.withdraw(50.0)
print 'balance after withdraw = ',a.getbalance()
a.deposit(50.0)
print 'balance after deposit = ',a.getbalance()

--
André Engels, andreengels at gmail.com


More information about the Tutor mailing list