tkinter属性错误

时间:2013-04-15 20:00:52

标签: python tkinter

我有一个BankAccount类,我用它来创建一个GUI,允许用户存款,提款,并查看他们的余额。

这是BankAccount类代码:

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

我收到的错误是我不知道这意味着什么或如何修复它。

Exception in Tkinter callback
Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/tkinter/__init__.py", line 1442, in __call__
    return self.func(*args)
  File "/Users/tinydancer9454/Documents/python/bankAccountGUI.py", line 49, in deposit
    balance= BankAccount.getBalance(self)
  File "/Users/tinydancer9454/Documents/python/bankAccountClass.py", line 24, in getBalance
    return round(self.__balance, 2)
AttributeError: 'bankAccountGUI' object has no attribute '_BankAccount__balance'

2 个答案:

答案 0 :(得分:3)

当您在balance= BankAccount.getBalance(self)函数中调用deposit时,您实际在做的是访问getBalance()类的BankAccount方法,使用它未初始化,并尝试传递另一个对象self。当您通过访问类而不是实例来调用方法时,您必须为其提供一个self对象才能实际工作。 BankAccount方法期望它们的self对象是BankAccount对象。您将传递一个BankAccountGUI对象,它不包含__balance属性。这就是它抛出这个错误的原因。

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

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

类似的东西。

答案 1 :(得分:0)

要理解错误消息中提及的变量_BankAccount__balance, 有关使用双下划线和“名称修改”的信息,请参阅the Python documentation

  

...由于类私有成员有一个有效的用例(即为了避免名称与子类定义的名称冲突),对这种称为名称修改的机制的支持有限。 __spam形式的任何标识符(至少两个前导下划线,最多一个尾随下划线)在文本上被替换为_classname__spam,其中classname是当前类名,其中前导下划线被剥离。

This question及其接受的答案也是提供信息的。

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

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