0

我是一名对计算机科学感兴趣的高中初级程序员。我一直在使用 Mike Dawson 的书自学 Python编程,Learning to Programming for the absolute 初学者 with Python, 3rd Edition. 我正在编写一个程序来练习我新获得的 OOP 知识。该程序模拟银行,玩家可以在其中开设银行账户、提取/存入现金、获取汇率、将资金从一个账户转移到另一个账户以及其他功能。我在程序中遇到了严重的问题,因为程序的主要部分模拟了用户可以访问的多个可访问帐户这一事实。我现在确定我应该如何或是否应该这样做,但我尝试编写一个名为 all_accounts 的空列表的类属性。每次实例化帐户时,都会将该实例附加到列表中。当玩家选择诸如提取/存入现金之类的菜单选项时,我希望访问列表中的实例,以便可以修改对象的属性(例如余额)。我不知道该怎么做,我一直在寻找答案大约 3 天,但没有找到任何东西。请记住,我是一个初学者程序员,所以我的代码可能会被认为写得不好。我将在下面发布整个代码,因为我认为人们有必要全面了解代码的工作原理和功能。此外,如果我的代码中有任何其他不正确或我可以做得更好的地方,请随时通知我。我总是乐于学习。如果我的代码中有任何其他不正确或我可以做得更好的地方,请随时通知我。我总是乐于学习。如果我的代码中有任何其他不正确或我可以做得更好的地方,请随时通知我。我总是乐于学习。

class Account(object):
    """An interactive bank account"""
    wallet = 0
    all_accounts = []

    # initial
    def __init__(self, ID, bal):
        self.ID = ID
        self.bal = bal
        print("A new account has been opened!")
        Account.all_accounts.append(self)                       

    def withdraw(self, w_input):
        if w_input < self.bal  or w_input == 0:
            print("That is not a valid amount. Sending you back to menu.\n")
            Menu()
        else:
            self.bal = self.bal - w_input
            print("You withdrew $" + str(w_input) + ".\n")
            wallet += w_input
            print("You wallet now contains $" + Account.wallet)
            Menu()

    def deposit(self):
        # Whatever



def Menu():
    print(
        """
0 - Leave the Virtual Bank
1 - Open a new account
2 - Withdraw money
3 - Deposit money
4 - Transfer money from one account to another
5 - Get exchange rates(Euro, Franc, Pounds, Yuan, Yen)
"""
        ) # Add more if necessary
    choice = input("What would you like to do?: ")
    while choice != "0":
        if choice == "1":
            account_name = input("What is your account's ID?: ")
            account_bal = float(input("How much money would you like to put into the account?(USD): "))
            account_name = Account(ID = account_name, bal = account_bal)
            Menu()

        elif choice == "2":
            account_choice = input("What is your account ID?: ")
            if account_choice in instance.Account.all_account:
                withdraw_choice = input("How much money would you like to withdraw?: ")
                account_choice.withdraw(w_input = withdraw_choice)
            else:
                print("Nope.")



    if choice == "0":
        print("\nThank you for visiting the virtual bank!")
        input("Press the [ENTER] key to exit the program.")


Menu()
4

2 回答 2

0

通常,您希望将调用代码与类的内部工作隔离开来。让Menu()函数直接检查包含所有帐户的列表是不灵活的,并且会在以后引起问题(如果您将列表换成数据库存储怎么办?)

相反,AccountManager类之类的东西可能是一个更好的主意:

class AccountManager(object):
    def __init__(self):
        self.accounts = []

    def create_account(self, id, balance):
        # You may want to check for uniqueness of id's here as well
        account = Account(id, balance)
        self.accounts.append(account)

    def get_account(self, id):
        for account in self.accounts:
            if account.id == id:
                return account
        return None # or a default value, or raise an exception

现在调用代码只需要告诉AccountManager创建和检索帐户,而不再关心它们是如何存储的。

于 2013-03-23T19:28:00.947 回答
0

正如 ACEfanatic02 所说,尽量将用户界面与应用程序的核心分开。

想想一个帐户必须有什么:

  • 唯一标识符
  • 平衡
  • (名称)客户
  • 交易清单

这些是实例属性。

还要考虑它必须能够做什么

  • 将钱存入账户
  • 从账户中提款
  • 转移到另一个帐户

这些是方法。

您可能还需要一种打印帐户文本表示的方法。这可以通过为类提供魔术方法来完成__str__

一个简单的例子:

def _checkamount(a):
    if a < 0:
        raise ValueError('amount must be >0')


class Account(object):

    maxnum = 0

    def __init__(self, client):
        self.client = client
        self.balance = 0.0
        self.transactions = []
        Account.maxnum = Account.maxnum + 1
        self.number = Account.maxnum

    def __str__(self):
        "Generate a human-readable representation of the Account."
        rv = 'Accountnumber: ' + str(self.number) + '\n'
        rv += 'Client: ' + str(self.client) + '\n'
        rv += 'Balance: ' + str(self.balance) + '\n'
        return rv

    def withdraw(self, amount):
        _checkamount(amount)
        if self.balance < amount:
            raise ValueError('overdraft!')
        self.balance -= amount
        self.transactions.append(("withdraw", amount))

    def deposit(self, amount):
        _checkamount(amount)
        self.balance += amount
        self.transactions.append(("deposit", amount))

    def transfer(self, amount, other):
        _checkamount(amount)
        self.balance -= amount
        self.transactions.append(("transfer", amount, other.number))
        other.balance += amount
        other.transactions.append(("transfer", amount, self.number))

我将此代码保存在一个名为account.py

交互式测试(使用Ipython,强烈推荐用于交互式实验):

In [1]: from account import Account

In [2]: a = Account('myself')

In [3]: b = Account('someoneelse')

In [4]: a.deposit(200)

In [5]: a.withdraw(10)

In [6]: b.deposit(50)

In [7]: a.transfer(25, b)

In [8]: print a.transactions
[('deposit', 200), ('withdraw', 10), ('transfer', 25, 2)]

In [9]: print b
Accountnumber: 2
Client: someoneelse
Balance: 75.0

In [10]: print b.transactions
[('deposit', 50), ('transfer', 25, 1)]

In [11]: print a
Accountnumber: 1
Client: myself
Balance: 165.0

In [12]: a.withdraw(1000)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-12-ffc10f6333fe> in <module>()
----> 1 a.withdraw(1000)

/home/rsmith/tmp/account.py in withdraw(self, amount)
     24         _checkamount(amount)
     25         if self.balance < amount:
---> 26             raise ValueError('overdraft!')
     27         self.balance -= amount
     28         self.transactions.append(("withdraw", amount))

ValueError: overdraft!

在这个测试中,我使用一个字符串作为client. 由于 Python 的动态特性,我稍后可以将其更改为例如一个类,并且只要 Client 有一个方法Client,代码仍然可以工作。__str__

于 2013-03-23T21:11:02.347 回答