2013-04-15 3 views
0

У меня есть класс BankAccount, который я использую для создания графического интерфейса пользователя, который позволяет пользователю делать депозит, делать вывод и видеть их баланс.ошибка атрибута tkinter

Это код класса 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' 

ответ

3

При вызова balance= BankAccount.getBalance(self) в вашей deposit функции, что вы на самом деле делаете доступ к getBalance() методу BankAccount класса, используя его неинициализированным и пытаетесь передать в другом объекте, как self. Когда вы вызываете метод, обращаясь к классу вместо экземпляра, вам нужно дать ему объект self, чтобы он действительно работал. Методы BankAccount ожидают, что их объекты self станут объектом BankAccount. Вместо этого вы передаете ему объект BankAccountGUI, который не содержит атрибута __balance. Вот почему он выбрасывает эту ошибку.

То, что вы должны делать это создание экземпляра BankAccount, а затем с помощью его метода:

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

Что-то вроде этого.

0

Чтобы понять упоминание в сообщении об ошибке переменной _BankAccount__balance, см the Python documentation на использовании двойных подчеркиваний и «имя коверкая»:

... Поскольку существует допустимое использование -case для членов класса-частного (а именно, чтобы избежать столкновения имен имен с именами, определенными подклассами), существует ограниченная поддержка такого механизма, называемого mangling. Любой идентификатор формы __spam (по крайней мере, два ведущих символа подчеркивания, не более одного символа подчеркивания) заменяется на текстовое слово _classname__spam, где classname - это текущее имя класса с разделительными подчеркиваниями.

This question и его принятый ответ также информативны.

Самый простой способ решить эту проблему - просто удалить все ведущие символы подчеркивания из ваших имен переменных класса. Или вы можете изменить self.__balance в функции BankAccount.getBalance() на self._BankAccount__balance.

Редактировать: Вы также передаете объект bankAccountGUI в качестве аргумента в функции getBalance, как self. Это должно быть только balance= BankAccount.getBalance(), без self.

+0

Я исправил это, и мне было просто интересно, знаете ли вы, почему появляется окно сообщения, в котором просто говорится «предупреждение», когда я нажимаю enter для ввода вклада. Я не смог найти какую-либо информацию о том, что это означает или что вызывает его. – tinydancer9454

+0

Junuxx, речь идет не о двойных подчеркиваниях, а о путанице между классами и экземплярами классов. Объект GUI должен создать экземпляр BankAccount, и все методы в BankAccountGUI должны работать от этого экземпляра, а не от самого объекта класса. – DaveTheScientist

+0

@tinydancer: Просто «оповещение» действительно немного бесполезно.Вам удалось выяснить, что вызвало это? – Junuxx

Смежные вопросы