Search code examples
pythonpython-3.xoopencapsulation

Encapsulation and constraining in Python


I have this test program:

class BankAccount:
     def __init__(self, name, balance):
         self.name = name
         self.balance = balance
         self.transaction_fee = 5.00
     def deposit(self, amount):
        self.balance = self.balance + amount
     def withdraw(self, amount):
        self.balance = self.balance - amount

I encapsulated the balance, name and transaction fee by doing the below:

class BankAccount:
     def __init__(self, name, balance):
         self._name = name
         self._balance = balance
         self._transaction_fee = 5.00
     def deposit(self, amount):
        self._balance = self._balance + amount
     def withdraw(self, amount):
        self.balance = self.balance - amount

Now I need to modify the BankAccount class to enforce the invariant that the account’s balance cannot ever become negative. This means that you should forbid negative deposits and forbid withdrawals that are more than the balance on the account.

I had thought to use a if/else statement in the deposit and withdraw function. For example:

 def deposit(self, amount):
    if amount >= 0:
          self._balance = self._balance + amount
    else ?????

The else part, I am not sure how to make it go back to the function and ask again for a proper value.

Is there another way to accomplish this too?

Thanks


Solution

  • In your methods, you could return a Boolean indicating success or failure. Then the calling code can deal with it appropriately.

    If you are worried that the calling code might ignore the return value and the transaction silently fail, you could raise an exception instead and leave the calling code to deal with that - something like this:

    class BankAccount:
         def __init__(self, name, balance):
             self._name = name
             self._balance = balance
             self._transaction_fee = 5.00
         def deposit(self, amount):
            if (self._balance + amount) < 0:
                raise Exception("Balance cannot go below 0.")
            else:
                self._balance = self._balance + amount
         def withdraw(self, amount):
            if (self._balance - amount) < 0:
                raise Exception("Balance cannot go below 0.")
            else:
                self._balance = self._balance - amount
    

    In real life you would create your own subclass of Exception and raise that.