-3

以下是我为当前工作构建的应用程序中使用的部分代码。运行以下代码时,我收到本文标题中所述的错误。tkinter 向导的代码来自http://mail.python.org/pipermail/tutor/2005-May/038686.html。我已经在自己的窗口中运行了代码并且它可以工作,但是当我将代码放在我的应用程序中时,它会遇到上述错误。

所以,这是我的问题:发生了什么事,我该如何解决?

from tkinter import *

#Start Code for the Introduction Wizard
def wizIntro():
    wizIntro = tkinter.Tk()



    #Title:
    wizIntro.title('Welcome to Training')

    #Content:
    page1 = Frame(wizIntro)
    Label(page1, text='', width=110).pack()
    Label(page1, text='--Welcome to Training--', width=85).pack()
    Label(page1, text='', width=85).pack()
    Label(page1, text='This tutorial will help you familiarize yourself with the program.  Following it is key to understanding', width=85).pack()
    Label(page1, text='the proper operation of the Laser Cutter.', width=85).pack()
    Label(page1, text='', width=90).pack()
    Label(page1, text='It is also important to follow every insrtuction exactly as stated, to avoid or minimize damage to the Laser', width=85).pack()
    Label(page1, text='Cutter and reduce the risk of injury to the operator and those around him.', width=85).pack()
    Label(page1, text='Therefore, all safety notices must be followed with extreme care.', width=110).pack()
    Label(page1, text='--Failure to follow all safety notices poses a severe risk of damage to the equipment and to the operator, which can be fatal--', width=110, fg='red').pack()
    Label(page1, text='', width=110).pack()
    Label(page1, text='Click Next to Continue...', width=110).pack()
    page1.pack()

    page2 = Frame(wizIntro)
    Label(page2, text='', width=110).pack()

    #Commands:
    pages = [page1, page2]
    current = page1
    def move(dirn):
        global current
        idx = pages.index(current) + dirn
        if not 0 <= idx < len(pages):
            return
        current = pages[idx]
        current.pack_forget()
        current.pack(side = TOP)

    def nex():
        move(+1)

    def prev():
        move(-1)

    Button(wizIntro, text='Previous', command=prev).pack(side = LEFT)
    Button(wizIntro, text='Next', command=nex).pack(side = RIGHT)

#End Code for the Introduction Wizard
4

3 回答 3

1

我不确定这是否是您的问题,但它肯定至少是一个相关的问题:

current = page1
def move(dirn):
    global current

这两个current变量指的不是同一个东西。第一个是函数中的局部变量wizintro。第二个是全局变量。

与其他错误相反,此特定错误的原因是这一行:

idx = pages.index(current) + dirn

您正在引用一个名为current. 您已经说过它是global,但您从未在全局范围内为它分配任何值。所以,它是未定义的。所以你得到一个例外。

如果您只是删除该global current行,那么它们会引用两个不同函数中的局部变量,这可能仍然不是您想要的。同一行实际上会给出相同的错误——现在它是一个局部变量,您正在使用它而没有在局部范围内为其分配任何值,但这并没有更好。

很明显,您想从外部范围move引用。current

如果您使用的是 Python 3.x,nonlocal current那可能就是您所追求的。

如果没有,有几个选择。

您可以使用“可变默认参数值”技巧。替换为一个元素 ( )current的 a ,然后作为额外参数传递给. 只要没有人覆盖默认值,就会有一个名为的局部变量,尽管它与外部范围内的变量不同,但它是对相同的引用,因此也是相同的变量。(有不同的技巧可以将局部变量绑定到闭包中,这对于来自 Scheme/Haskell/etc. 背景的人可能会感觉更友好,但效果是一样的。)listcurrent=[page1]current=currentmovemovecurrentcurrent[0]

或者您可以current在两个范围内都创建一个全局变量。

或者,走相反的方向:wizintro变成一个类,move朋友变成方法,current变成一个实例变量。这看起来真的像你在这里的目的。

于 2013-03-18T18:06:03.983 回答
0

您不能使用global从外部范围更改非全局变量,只能更改全局(模块级)变量。Python 3.xnonlocal可以做到这一点。考虑改变你的逻辑。

于 2013-03-18T18:08:01.723 回答
0

您遇到的麻烦是因为current不是全局变量,而是wizIntro函数中的局部变量。您的嵌套函数move尝试访问它,但它的global语句在全局命名空间中找不到该值。这意味着当您稍后尝试访问它时,您会得到一个NameError.

如果您使用的是 Python 2,则没有任何好方法可以从嵌套函数中访问外部函数命名空间的变量。我认为你能做的最好的事情就是声明current是全局的wizIntro(在你第一次分配给它之前)。Python 3 引入了nonlocal可以使用当前结构的关键字(只需替换您当前的global语句。

于 2013-03-18T18:09:24.153 回答