我是高中初级程序员,对计算机科学感兴趣。我一直在教自己使用Mike Dawson的书编写Python程序,学习为Python初学者编写第3版。我正在编写一个程序来练习我新获得的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()
答案 0 :(得分: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
创建和检索帐户,并且不再关心它们的存储方式。
答案 1 :(得分: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
类,如果客户端使用__str__
方法,代码仍然有效。