NameError:未定义全局名称“current”

时间:2013-03-18 17:42:03

标签: python tkinter wizard

以下是我正在为我目前的工作建立的应用程序中使用的代码的一部分。运行以下代码时,我收到此帖子标题中所述的错误。 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

3 个答案:

答案 0 :(得分: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替换为list个元素(current=[page1]),然后将current=current作为额外参数传递给move。只要没有人覆盖默认值,move将有一个名为current的局部变量,尽管与外部范围中的变量不同,但它是一个参考对于相同的,所以current[0] 相同的变量。 (有一些不同的技巧可以将局部变量绑定到一个闭包中,这对于来自Scheme / Haskell /等背景的人来说可能会更友好,但效果是一样的。)

或者你可以在两个范围内使current成为全局。

或者,转向相反的方向:将wizintro转换为类move,将朋友转为方法,将current转换为实例变量。这看起来就像你要去的那样。

答案 1 :(得分:0)

您不能使用global从外部作用域更改非全局变量,只能更改全局(模块级)变量。 Python 3.x有nonlocal。考虑改变你的逻辑。

答案 2 :(得分:0)

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

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