Попытка передать экземпляр класса в другой файл - PullRequest
2 голосов
/ 15 марта 2019

Я пытаюсь вызвать мой файл класса из другого файла, создать экземпляр объекта (который работает) - и затем запустить одну из функций в моем втором файле (который не работает).

Я получаю сообщение об ошибке при попытке вызвать одну из функций во втором файле. Я думаю, что понимаю, почему это происходит, так как экземпляр был создан в файле 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')

1 Ответ

1 голос
/ 15 марта 2019

Мне кажется, я понимаю, почему это происходит, поскольку экземпляр был создан в файле 1, а этот файл 1 не имеет доступа к методу из второго файла (create_account).

Это не совсем проблема - дело не в том, что экземпляр не имеет доступа к методу, потому что он находится в другом файле, а в том, что метод определен для другого класса в целом.

Когда вы пишете obj1 = BankAccount()Вы помещаете ссылку на экземпляр BankAccount в переменную obj1.Затем, когда вы пишете obj1.Database. ..., Python пытается получить доступ к методу Database из вашего obj1, то есть BankAccount.Поскольку вы не определили метод с именем Database в своем классе BankAccount в файле 1, возникает ошибка.

Если вы хотите создать взаимодействия между экземплярами разных классов, вам необходимо «подключиться"их как-то.Обычно это делается либо путем передачи экземпляра объекта A в метод, вызываемый для экземпляра другого объекта B , либо путем явного создания экземпляра объекта A внутри метода объекта B.Рассмотрите этот пример, который показывает это:

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()        

Обратите внимание, что этот пример кода написан для одного файла, но он будет работать так же хорошо для двух отдельных файлов, если соответствующий импорт выполняется правильно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...