获取NameError:在赋值之前引用的自由变量,但无法看到我在哪里这样做

时间:2017-05-02 20:03:48

标签: python sql tkinter pypyodbc

我正在尝试为我的应用程序创建一个基本的登录框架(不要担心它复杂,它是A Level项目)。在checklogin函数中,我试图检索用户输入的用户名,并查看它是否已在数据库中,并将添加一些内容以检查密码是否稍后匹配。但是我一直收到错误' NameError:free variable' userentry'在封闭范围内转让前引用'。看到这个错误,它说通常的原因是因为' userentry'正在被重新分配到以后的同一个功能。但是,我很难看到这种情况。任何帮助将不胜感激。

class Login(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        self.controller = controller
        self.configure(background="lightgreen")

    def check_login():
        sql = "SELECT Password FROM Player WHERE Username IN (?)"
        parameters = (userentry.get())
        cursor.execute(sql, parameters)
        print(cursor.fetchall())

    for col in range(5):
        self.grid_columnconfigure(col, minsize=50)

    for row in range(7):
        self.grid_rowconfigure(row, minsize=60)

    titlelbl = tk.Label(self,
                        text="Please enter your username and password",
                        font = "Verdana 20 bold",
                        fg="black",
                        bg="lightgreen")

    titlelbl.grid(column=1,
                  row=0,
                  columnspan=3)

    usernamelbl = tk.Label(self,
                           text="Username:",
                           font="Verdana 14",
                           bg="lightgreen")

    usernamelbl.grid(column=1,
                     row=2)

    passwordlbl = tk.Label(self,
                           text="Password:",
                           font="Verdana 14",
                           bg="lightgreen")

    passwordlbl.grid(column=1,
                     row=4)

    signupbtn = tk.Button(self,
                          text="Sign Up",
                          fg="lightgreen",
                          bg="darkgreen",
                          height="3",
                          width="12",
                          command = lambda: controller.show_frame("SignUp"))

    signupbtn.grid(column=3,
                   row=6)

    loginbtn = tk.Button(self,
                         text="Log In",
                         fg="lightgreen",
                         bg="darkgreen",
                         height="3",
                         width="12",
                         command = check_login())

    loginbtn.grid(column=1,
                  row=6)

    userentry = tk.Entry(self)

    userentry.grid(column=3,
                       row=2)

    passentry = tk.Entry(self,
                         show="*")

    passentry.grid(column=3,
                       row=4)                       

1 个答案:

答案 0 :(得分:0)

在此代码中

loginbtn = tk.Button(self,
                     text="Log In",
                     fg="lightgreen",
                     bg="darkgreen",
                     height="3",
                     width="12",
                     command = check_login())

command = check_login()更改为command = check_login(不括括号)。

check_login是函数对象。 check_login() 调用函数对象并计算函数的返回值。

括号告诉Python立即调用该函数。这里,当定义tk.Button时,尚未定义userentry变量。这就是您在调用NameError时获得check_login的原因。

因此,如果您使用command = check_login,则tk.Button会收到函数对象check_login,然后在按下按钮后可以调用它。