Python tkinter属性错误

Python tkinter属性错误,python,tkinter,Python,Tkinter,我使用BankAccount类创建GUI,允许用户存款、取款和查看余额 这是银行账户类别代码: class BankAccount(object): """ creates a bank account with the owner's name and a balance """ def __init__(self, name, balance = 0): self.__name = name self.__balance =

我使用BankAccount类创建GUI,允许用户存款、取款和查看余额

这是银行账户类别代码:

class BankAccount(object):
    """ creates a bank account with the 
        owner's name and a balance """
    def __init__(self, name, balance = 0):
        self.__name = name
        self.__balance = balance

    def getName(self):
        """ returns the owner's name """
        return self.__name

    def getBalance(self):
        """ returns the current balance """
        return round(self.__balance, 2)

    def deposit(self, amount):
        """ deposits amount into the account """
        self.__balance += amount

    def withdraw(self, amount):
        """ withdraws amount from the account
            returns 'overdrawn' if balance is too low """
        if self.__balance >= amount:
            self.__balance -= amount
        else:
            return 'overdrawn'

    def __str__(self):
        """ return a string representation of the account """
        return self.__name + ' has a balance of $' + str(round(self.__balance, 2))
这是GUI代码:

from tkinter import *
from bankAccountClass import BankAccount




class bankAccountGUI(Frame):
    def __init__(self):
        """Set up the GUI"""
        self.__balance= 0
        Frame.__init__(self)
        self.master.title('Bank Account')
        self.grid()

        depositLabel = Label(self, text= "Make Deposit")
        depositLabel.grid(row = 0, column = 0)
        self.depositVar= DoubleVar()
        depositEntry = Entry(self, textvariable= self.depositVar)
        depositEntry.grid(row = 0, column = 1)

        withdrawLabel= Label(self, text= "Make Withdrawal")
        withdrawLabel.grid(row = 1, column = 0)
        self.withdrawVar = DoubleVar()
        withdrawEntry= Entry(self, textvariable= self.withdrawVar)
        withdrawEntry.grid(row = 1, column = 1)


        button_1= Button(self, text = "Enter", command = self.deposit)
        button_1.grid(row = 0, column = 2)

        button_2= Button(self, text = "Enter", command = self.withdrawal)
        button_2.grid(row = 1, column = 2)


    def deposit(self):
        """event handler for button_1"""
        try:
            amount= self.depositVar.get()
            balance= BankAccount.getBalance(self)
            if amount <= 0:
                messagebox.showerror(message= 'Deposit must be greater than 0')
            else:
                balance= BankAccount.deposit(self, amount)
                messagebox.showinfo(title= "Current Balance",
                                    message= "$" + self.balance,
                                    parent= self)
        except ValueError:
            messagebox.showerror(message= "Invalid deposit amount")


    def withdrawal(self):
        """event handler for button_2"""
        try:
            amount= self.withdrawVar.get()
            balance= BankAccount.getBalance(self)
            if amount > self.balance:
                messagebox.showerror(message= "Insufficient funds")
            else:
                balance= BankAccount.withdraw(self, amount)
                messagebox.showinfo(title= "Current Balance",
                                    message= "$" + self.balance,
                                    parent= self)
        except ValueError:
            messagebox.showerror(message= "Invalid withdrawal amount")

def main():
    """instantiate and pop up the window"""
    bankAccountGUI().mainloop()

要了解错误消息中提到的变量
\u BankAccount\u balance
, 有关双下划线和“名称混乱”的使用,请参见:

。。。由于类私有成员有一个有效的用例(即避免名称与子类定义的名称发生名称冲突),因此对这种称为名称混乱的机制的支持有限。格式为
\uuuu spam
(至少两个前导下划线,最多一个尾随下划线)的任何标识符都将以文本形式替换为
\u classname\uuuuu spam
,其中classname是当前类名,前导下划线已去除

其公认的答案也提供了信息

解决此问题的最简单方法是从类变量名中删除所有前导下划线。或者,您可以将
BankAccount.getBalance()
函数中的
self.\u balance
更改为
self.\u BankAccount\u balance


编辑:您还将
bankAccountGUI
对象作为
getBalance
函数中的参数传递,作为
self
。它应该是
balance=BankAccount.getBalance()
,而不是
self

,以理解错误消息中提到的变量
\u BankAccount\u balance
, 有关双下划线和“名称混乱”的使用,请参见:

。。。由于类私有成员有一个有效的用例(即避免名称与子类定义的名称发生名称冲突),因此对这种称为名称混乱的机制的支持有限。格式为
\uuuu spam
(至少两个前导下划线,最多一个尾随下划线)的任何标识符都将以文本形式替换为
\u classname\uuuuu spam
,其中classname是当前类名,前导下划线已去除

其公认的答案也提供了信息

解决此问题的最简单方法是从类变量名中删除所有前导下划线。或者,您可以将
BankAccount.getBalance()
函数中的
self.\u balance
更改为
self.\u BankAccount\u balance


编辑:您还将
bankAccountGUI
对象作为
getBalance
函数中的参数传递,作为
self
。调用
balance=BankAccount.getBalance()
时,它应该是
balance=BankAccount.getBalance(self)
而不是
self

,在您的
deposit
函数中,您实际做的是访问
BankAccount
类的
getBalance()
方法,使用它未初始化,并尝试将另一个对象作为
self
传入。当您通过访问类而不是实例来调用方法时,您必须给它一个
self
对象,它才能真正工作。BankAccount方法期望它们的
self
对象是BankAccount对象。您将向其传递一个BankAccountGUI对象,该对象不包含
\u balance
属性。这就是为什么它会抛出那个错误

您应该做的是创建BankAccount的实例,然后使用其方法:

account = BankAccount()
balance = account.getBalance()

类似于此。

存款
函数中调用
balance=BankAccount.getBalance(self)
时,实际操作是访问
BankAccount
类的
getBalance()
方法,将其未初始化,并尝试以
self
的形式传入另一个对象。当您通过访问类而不是实例来调用方法时,您必须给它一个
self
对象,它才能真正工作。BankAccount方法期望它们的
self
对象是BankAccount对象。您将向其传递一个BankAccountGUI对象,该对象不包含
\u balance
属性。这就是为什么它会抛出那个错误

您应该做的是创建BankAccount的实例,然后使用其方法:

account = BankAccount()
balance = account.getBalance()

诸如此类。

我已经解决了这个问题,我想知道您是否知道,当我按enter键输入存款条目时,为什么会弹出一个只显示“警报”的消息框。我一直找不到任何关于这意味着什么或者是什么导致itJunuxx的信息,这不是关于双下划线,它实际上混淆了类和类的实例。GUI对象应该创建BankAccount的一个实例,BankAccountGUI中的所有方法都应该在该实例上运行,而不是在类对象本身上运行。@tinydancer:仅仅是“警报”确实没有什么帮助。你找到了它的原因吗?@DaveTheScientist:你是对的,尽管我认为“弄脏”这个名字实际上并不清楚,我的回答确实部分解释了“他们不知道它的意思的错误”。这可能是真的。了解所有名称的混乱是一件非常好的事情。我已经解决了这个问题,我只是想知道,为什么当我按enter键输入存款条目时,会弹出一个简单地显示“警报”的消息框。我一直找不到任何关于这意味着什么或者是什么导致itJunuxx的信息,这不是关于双下划线,它实际上混淆了类和类的实例。GUI对象应该创建BankAccount的一个实例,BankAccountGUI中的所有方法都应该在该实例上运行,而不是在类对象本身上运行。@tinydancer:仅仅是“警报”确实没有什么帮助。你找到了它的原因吗?@DaveTheScientist:你是对的,尽管我认为“弄脏”这个名字实际上并不清楚,我的回答确实部分解释了“他们不知道它的意思的错误”。这可能是真的。了解整个曼林