Python 中的封装和约束

Encapsulation and constraining in Python

我有这个测试程序:

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

我通过以下操作封装了余额、姓名和交易费用:

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

现在我需要修改 BankAccount class 以强制执行帐户余额永远不会变为负数的不变性。这意味着您应该禁止负存款,禁止大于账户余额的提款。

我曾想过在存取款函数中使用if/else语句。例如:

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

else 部分,我不确定如何让它返回到函数并再次询问适当的值。

还有其他方法可以做到这一点吗?

谢谢

在您的方法中,您可以 return 一个指示成功或失败的布尔值。那么调用代码就可以适当的处理了。

如果您担心调用代码可能会忽略 return 值并且事务默默地失败,您可以改为引发异常并让调用代码来处理它 - 如下所示:

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

在现实生活中,您会创建自己的 Exception 子类并引发它。

处理此问题的一种方法是为该模块定义一个例外 class(例如 AccountError)并在有人试图存入负数额(或做任何其他事情)时引发该例外这是不允许的)。

在调用 deposit() 方法的地方,您可以捕获异常(借助 try-except-block)并允许用户重试如果他们输入了无效值。

它可能看起来像这样:

class AccountError(Exception):
    """Module specific error"""


class BankAccount:
    ...
    ...
    ...
    def deposit(self, amount):
        if amount >= 0:
            self._balance = self._balance + amount
        else:
            raise AccountError("Deposit amount cannot be negative")

(当然,您可以向例外添加更多信息和功能。)

在调用代码的地方:

account = BankAccount()
...
...
try:
    account.deposit(negative_amount)
except AccountError as exc:
    # Code that allows you to retry the deposit.
    # Implementation depends on your program structure.

整个块可以嵌入到 forwhile 循环中,并进行一定次数的重试,或者任何对你的情况有意义的方法。

具体实现将取决于您的程序的结构和功能。