我试图从另一个文件中调用我的类文件,实例化该对象(起作用)-然后在第二个文件中触发一个功能(不起作用)。
当我尝试调用第二个文件中的函数之一时出现错误。我想我理解为什么会发生这种情况,因为该实例是在文件1中创建的,而该文件1无法访问 第二个文件(create_account)中的方法。但是有什么办法解决吗?
如果在第二个文件中添加类定义,则可以使其正常工作。但是我认为如果将它们保存在第一个文件中,我的设计会更好
例如,该错误-
Traceback (most recent call last):
File "C:\Users\hassy\Google Drive\Python\bnk\bank_account\database.py", line 130, in <module>
obj1.Database.create_account("Frank Sanchez", 135063543, 2380, 100, 'bank_account')
AttributeError: 'BankAccount' object has no attribute 'Database'
class BankAccount:
def __init__(self, name, social, account_number, balance, acctype):
self.name = name
self.social = social
self.account_number = account_number
self.balance = balance
self.acctype = acctype
class CreditCard(BankAccount):
def __init__(self, name, social, account_number, balance, acctype, card_no, credit_score=None, credit_limit=None):
super().__init__(name, social, account_number, balance, acctype)
self.card_no = card_no
self.credit_score = credit_score
self.credit_limit = credit_limit
class SavingsAccount(BankAccount):
def __init__(self, name, social, account_number, balance, acctype, rate=None):
super().__init__(name, social, account_number, balance, acctype)
self.rate = None
数据库文件(第二个文件)-
import sqlite3
import secrets
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email import encoders
import send_email
#import account
from account import BankAccount
from account import CreditCard
conn = sqlite3.connect('bank_account.db')
c = conn.cursor()
def create_account(self, name, social, account_number, balance, acctype, card_no=None, credit_score=None, credit_limit=None):
""" create different accounts based on account type passed in """
with conn:
if acctype == 'bank_account':
c.execute("INSERT INTO {} VALUES (:name, :social, :account_number, :balance, :pin)".format(acctype),
{'name':name, 'social': social,'account_number': account_number, 'balance':balance, 'pin':''})
print("New account: {} has been created, acc # is: {}".format(acctype, account_number))
elif acctype == 'savings_account':
c.execute("INSERT INTO {} VALUES (:name, :social, :account_number, :balance, :rate)".format(acctype),
{'name':name, 'social': social,'account_number': account_number, 'balance':balance, 'rate':''})
print("New account: {} has been created, acc # is: {}".format(acctype, account_number))
elif acctype == 'credit_card':
c.execute("INSERT INTO credit_card VALUES (:name, :social, :account_number, :balance, :card_no,:credit_score, :credit_limit, :pin)",
{'name':name, 'social': social,'account_number': account_number, 'balance':balance, 'card_no'
:card_no, 'credit_score':credit_score, 'credit_limit':credit_limit, 'pin':'' })
print("New account: {} has been created, acc # is: {}".format(acctype, account_number))
conn.commit()
def get_account(self,account_number, acctype):
""" Show all rows in DB for the the account type passed in """
with conn:
account_find = c.execute("SELECT * from {} WHERE account_number=:account_number".format(acctype),
{'account_number':account_number})
account_found = c.fetchone()
if not account_found:
print("No {} matching that number could be found".format(acctype))
else:
print("Account type: {} exists!".format(acctype))
print(account_found)
return(account_found)
def get_balance(self, account_number, acctype):
""" get balance from account """
with conn:
balance = c.execute("SELECT balance from {} WHERE account_number=:account_number".format(acctype),
{'account_number':account_number})
balance = c.fetchone()
print("The balance for account number: {} is ${}".format(account_number, balance[0]))
notif_set = BankAccount.get_notif(self, account_number, acctype)
if notif_set is None:
print("No notifications are set for this user")
else:
notif_balance = notif_set[4]
name = notif_set[0]
if notif_balance == 1:
notify = send_email.send_email(account_number, acctype, 'Balance', balance, balance, name)
return(balance[0])
def deposit(self, account_number, acctype, amount):
""" Deposit funds into the account number + acctype for the account passed in """
with conn:
account_found = BankAccount.get_account(self, account_number, acctype)
if account_found:
existing_bal = account_found[3]
c.execute("""UPDATE {} SET balance=balance +:amount
WHERE account_number =:account_number""".format(acctype),
{'account_number':account_number, 'amount':amount})
new_bal = existing_bal + (int(amount))
print("${} has been deposited to account {} and the new balance is ${}".format(amount, account_number, existing_bal + (int(amount))))
# Check email configurations are turned on for deposits
notif_set = notifications.get_notif(self, account_number, acctype)
if notif_set is None:
print("No notifications are set for this user")
else:
notif_deposits = notif_set[5]
name = notif_set[0]
if notif_deposits == 1:
notify = send_email.send_email(account_number, acctype, 'Deposit', amount, new_bal, name)
def withdraw(self, account_number, acctype, amount):
""" withdraw funds from the bank account number passed in """
with conn:
account_found = BankAccount.get_account(self, account_number, acctype)
existing_bal = account_found[3]
if account_found:
c.execute("""UPDATE bank_account SET balance=balance -:amount
WHERE account_number =:account_number""",
{'account_number':account_number, 'amount':amount})
new_bal = existing_bal - (int(amount))
conn.commit()
print("${} has been withdrawn from account {} and the new balance is ${}".format(amount, account_number, existing_bal - (int(amount))))
notif_set = BankAccount.get_notif(self, account_number, acctype)
if notif_set is None:
print("No notifications have been set for this acct")
else:
notif_withdraw = notif_set[7]
name = notif_set[0]
if notif_withdraw == 1:
notify = send_email.send_email(account_number, acctype, 'Withdraw', amount, new_bal, name)
else:
print("Withdrawl notifications have been turned off")
if account_found and new_bal < 0 and notif_set is not None:
notify_o = send_email.send_email(account_number, acctype, 'Overdraft', amount, new_bal, name)
conn.commit()
if __name__ == '__main__':
obj1 = BankAccount("Frank Sanchez", 135063543, 2380, 100, 'bank_account')
obj1.Database.create_account("Frank Sanchez", 135063543, 2380, 100, 'bank_account')
答案 0 :(得分:1)
我想我理解为什么会发生这种情况,因为实例是在文件1中创建的,并且文件1无法从第二个文件(create_account)访问该方法。
这不完全是问题-不是因为实例不在另一个文件中而导致实例无法访问该方法,而是该方法是为另一个类定义的。
在编写obj1 = BankAccount()
时,将对BankAccount
实例的引用放入变量obj1
中。然后,当您编写obj1.Database. ...
时,Python会尝试从Database
中访问名为obj1
的方法,即BankAccount
。由于您没有在Database
类上定义返回到文件1的名为BankAccount
的方法,因此会引发错误。
如果要在不同类的实例之间创建交互,则需要以某种方式“连接”它们。通常,这可以通过以下方式完成:将对象A的实例传递给在另一个对象B的实例上调用的方法,或者通过在对象B的方法内部显式创建对象A的实例。考虑显示以下内容的示例:
class Account:
pass
class Database:
def __init__(self):
self.accounts = []
def add_account(self, acc):
if not isinstance(acc, Account):
raise TypeError("bad input")
self.accounts.append(acc)
def create_default_account(self)
default_account = Account()
self.accounts.append(default_account)
account = Account()
db = Database()
# passes an Account object as an argument to
# a Database object method call
db.add_account(account)
# calls a Database object method which internally
# creates and processes an Account object
db.create_default_account()
请注意,此示例代码写在单个文件上,但是只要正确完成了相应的导入,它就可以在两个单独的文件上工作。