当在类中定义属性时,Python AttributeError对象没有属性

时间:2018-03-31 19:34:26

标签: python attributes kivy attributeerror

我正在使用Kivy在工作中编写一个实用平台,供我的同事在前台使用。我无法将用户分配给会话。这是我的代码:

masterControl.py

from kivy.uix.boxlayout import BoxLayout

class MasterControl(BoxLayout):
    def __init__(self, **kwargs):
        super(MasterControl, self).__init__(**kwargs)
        m_currentUser = None

    def loginUser(self, emp):
        self.m_currentUser = emp
        print "I made it to login!"
        # remove login widget, add the rest of the UI according to the security level of the use

login.py

from kivy.uix.anchorlayout import AnchorLayout 
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.uix.textinput import TextInput
from kivy.uix.boxlayout import BoxLayout

from coreAPI.mastercontrol import MasterControl
from employee import Employee, getEmployees

class LoginWidget(AnchorLayout):
    def __init__(self, **kwargs):
        super(LoginWidget, self).__init__(**kwargs)

        def loginBtnHandle(instance):
            empList = getEmployees()
            for emp in empList:
                if emp.m_aNum == uNameInput.text:
                    if emp.authenticate(pWordInput.text):
                        self.parent.loginUser(emp) # Here is where I get  AttributeError: 'MasterControl' object has no attribute 'loginUser'

        box = BoxLayout(orientation = 'vertical', size = (300, 110), size_hint = (None, None), spacing = 10)

        uNameInput = TextInput(hint_text = 'Username', 
                multiline = False, 
                size = (300, 30), 
                size_hint = (None, None), 
                cursor_color = [0,0,0,1], 
                write_tab = False)

        pWordInput = TextInput(hint_text = 'Password', 
                multiline = False, 
                size = (300, 30), 
                size_hint = (None, None), 
                cursor_color = [0,0,0,1], 
                password = True, 
                write_tab = False)

        loginBtn = Button(text = 'Login', size = (300, 50), size_hint = (None, None))
        loginBtn.bind(on_press = loginBtnHandle)
        loginBtn.bind(on_enter = loginBtnHandle)

        box.add_widget(uNameInput)
        box.add_widget(pWordInput)
        box.add_widget(loginBtn)

        self.add_widget(box)

employee.py

from passlib.hash import pbkdf2_sha256
import pickle
import os

class Employee():
    def __init__(self, name, aNumber, password, clearance):
        self.m_name = name
        self.m_aNum = aNumber
        self.m_pWordHash = pbkdf2_sha256.hash(password) # Only store the password hash.  NEVER the password text
        self.m_clearance = clearance

    def authenticate(self, attempt):
        return pbkdf2_sha256.verify(attempt, self.m_pWordHash)

    def serialize(self):
        filename = 'users/' + self.m_aNum + '.emp'
        frozen = pickle.dumps(self)
        f = open(filename, 'w')
        f.write(frozen)
        f.close()
        return frozen

def getEmployees():
    empList = []
    path = 'users/'
    for filename in os.listdir(path):
        f = open(path + filename, 'r')
        contents = f.read()
        empList.append(pickle.loads(contents))
    return empList

tempEmp = Employee('Tester', 'A12345678', 'password', 'HIGH')
tempEmp.serialize()

用户通过身份验证后,登录窗口小部件会调用mastercontrol的loginUser方法。当它执行此操作时,Python会抛出AttributeError: 'MasterControl' object has no attribute 'loginUser'。据我所知,它应该可以致电loginUser。我已经完成了缩进,并排除了员工对象的反序列化错误。

1 个答案:

答案 0 :(得分:0)

问题

AttributeError: 'MasterControl' object has no attribute 'loginUser'是由于没有实例化MasterControl类。

解决方案

有两种解决方案。第一个解决方案假设MasterControl是根小部件。第二个解决方案假设LoginWidget是根小部件。有关详细信息,请参阅代码段和输出。

解决方案1 ​​ - masterControl.py

  1. 从kivy.properties导入ObjectProperty 添加
  2. 从登录导入LoginWidget
  3. 添加
  4. m_currentUser 定义为 ObjectProperty 并将其初始化为
  5. LoginWidget 添加到 MasterControl
  6. 片段

    from kivy.properties import ObjectProperty
    
    from login import LoginWidget
    
    
    class MasterControl(BoxLayout):
        m_currentUser = ObjectProperty(None)
    
        def __init__(self, **kwargs):
            super(MasterControl, self).__init__(**kwargs)
            self.add_widget(LoginWidget())
    

    解决方案1 ​​ - login.py

    1. 从coreAPI.mastercontrol导入MasterControl
    2. 删除/注释掉

      解决方案2 - login.py

      1. 从kivy.properties导入ObjectProperty 添加
      2. 定义 ObjectProperty ,例如 masterControl
      3. 立即启动类MasterControl 并将其连接到新的ObjectProperty, masterControl
      4. self.parent.loginUser(emp)替换为 self.masterControl.loginUser(emp)
      5. 片段

        from kivy.properties import ObjectProperty
        
        
        class LoginWidget(AnchorLayout):
            masterControl = ObjectProperty(None)
        
            def __init__(self, **kwargs):
                super(LoginWidget, self).__init__(**kwargs)
                self.masterControl = MasterControl()
        
                def loginBtnHandle(instance):
                    empList = getEmployees()
                    for emp in empList:
                        if emp.m_aNum == uNameInput.text:
                            if emp.authenticate(pWordInput.text):
                                self.masterControl.loginUser(emp)
        

        解决方案2 - masterControl.py

        1. 从kivy.properties导入ObjectProperty 添加
        2. m_currentUser 定义为 ObjectProperty 并将其初始化为
        3. 片段

          from kivy.properties import ObjectProperty
          
          
          class MasterControl(BoxLayout):
              m_currentUser = ObjectProperty(None)
          
              def __init__(self, **kwargs):
                  super(MasterControl, self).__init__(**kwargs)
          
              def loginUser(self, emp):
                  self.m_currentUser = emp
          

          输出

          Img01 - App Startup Img02 - Called MasterControl.loginUser Successfully