Python - 全局名称未定义

时间:2013-07-15 05:26:39

标签: python canvas global-variables undefined

嘿,我在过去的这一天被这个简单的错误所困扰,并且无法通过它。 这是我收到此错误消息的代码的一部分:

Exception in Tkinter callback
Traceback (most recent call last):
  File "/usr/lib/python3.2/tkinter/__init__.py", line 1402, in __call__
    return self.func(*args)
  File "/home/ppppwn3d/workspace/Python/JailBreakBob/JailBreakBob.py", line 110, in buttonclick_mainscreen
    gamescreen()
  File "/home/ppppwn3d/workspace/Python/JailBreakBob/JailBreakBob.py", line 58, in gamescreen
    if pressed == 8 and e1 == answerlistx[randomimage] and e2 == answerlisty[randomimage]:
NameError: global name 'pressed' is not defined

def gamescreen():
    imagelist = ["1.gif","2.gif","3.gif","4.gif","5.gif","6.gif","7.gif","8.gif","9.gif","10.gif","11.gif","12.gif","13.gif","14.gif","15.gif","16.gif","17.gif","18.gif","19.gif","20.gif","21.gif","22.gif","23.gif","24.gif","25.gif","26.gif","27.gif","28.gif","29.gif","30.gif","31.gif","32.gif","33.gif","34.gif","35.gif","36.gif","37.gif","38.gif","39.gif","40.gif","41.gif","42.gif","43.gif","44.gif","45.gif","46.gif","47.gif","48.gif","49.gif","50.gif"]
    answerlistx = [-1, -3, 3, 4, -7, 8, 9, 10, -10, 2, -7, 7, -1, -5, -6, -9, -7, 10, -4, 8, 1, -8, -10, -1, -3, -7, -3, 7, 3, -4, 1, -8, -4, 9, -5, -10, 10, 2, 2, -10, 4, 9, -3, 6, 10, -6, 4, 9, -10, -10]
    answerlisty = [3, -6, -5, 3, -2, 4, -4, -3, 4, -6, 1, 2, 2, 3, 2, -1, -5, 1, -3, 1, -2, -2, -5, -3, -2, -6, -3, 6, 2, 0, -5, 6, -4, 4, 1, -6, 0, -6, 5, 2, 4, -4, -2, 0, -3, -6, -4, 1, -3, 1]

    canvas.bind("<Button-1>", buttonclick_gamescreen)
    canvas.pack(expand = YES, fill = BOTH)
    photo = PhotoImage(file="gamescreen.gif")
    canvas.create_image(1, 1, image = photo, anchor = NW)
    e1 = Entry(canvas, width = 11)
    e2 = Entry(canvas, width = 11)
    canvas.create_window(390, 501, window=e1, anchor = NW)
    canvas.create_window(551, 501, window=e2, anchor = NW)
    canvas.after(1, countdowntimer)
    while cdtimer != 0:
        randomimage = random.randrange(0,49+1)
        game = PhotoImage(file=imagelist[randomimage])
        images = canvas.create_image(30, 65, image = game, anchor = NW)
        if pressed == 8 and e1 == answerlistx[randomimage] and e2 == answerlisty[randomimage]:
             canvas.delete(images)
             randomimage = random.randrange(0,49+1)
             scorecounter = scorecounter + 1
             game = PhotoImage(file=imagelist[randomimage])
             images = canvas.create_image(30, 65, image = game, anchor = NW)
        elif pressed == 8 and e1 != answerlistx[randomimage] or e2 !=     answerlisty[randomimage]:
            wronganswer = canvas.create_text(400, 200, text="Incorrect", font="Ubuntu 29 bold", fill=red, anchor=NW)
            e1.delete(0.0,END)   
            e2.delete(0.0,END)
            canvas.after(1500,(canvas.delete(wronganswer)))

但我确实在

中定义了它
def buttonclick_gamescreen(event):
    global pressed
    pressed = ""

    if event.x >853 and event.x <957 and event.y > 8 and event.y < 56 : pressed = 7 
    if event.x >666 and event.x <947 and event.y > 491 and event.y < 534 : pressed = 8 
    if pressed == 7 :
        window.destroy()
    if pressed == 8:
        print("next button")

这令我感到困惑。 有人可以解释一下为什么会发生这种情况以及我该怎么做才能解决这个问题? 提前致谢

PS:基本上我在这里尝试的是当按下“下一个”按钮时它将检查e1和e2,如果那里的字符串与列表中的答案匹配,那么它将随机地将另一个图像加载到画布。

3 个答案:

答案 0 :(得分:1)

您未在模块级别定义pressed。至少你应该这样做:

pressed = ''

def buttonclick_gamescreen(event):
    global pressed
    ...
def gamescreen():
    ...

或者您可以将代码重组为类:

class Application(tk.Frame):
    def __init__(self, ...):
        self.pressed = ''
    def gamescreen():
        ...
    ...

或者您可以使用StringVar来追踪值。

答案 1 :(得分:1)

虽然你已经在 def buttonclick_gamescreen(事件)中声明了全局变量:但问题是你的 def gamescreen(): def buttonclick_gamescreen之前被调用(事件):,因此python运行时无法在内存中查找名为press的引用,因为从未执行过该行代码。为了说明这会产生什么影响,请考虑以下事项:

def do_something():
    global name
    name = 10
    print name

def do_somehting_else():
    if name == 10:
        print "Valid"

此处名称在函数体内定义为全局。所以,当我们打电话时:

do_something()
do_somehting_else()

我们得到了,

>>> 10
>>> Valid

但是,如果我们将函数调用的顺序更改为:

do_somehting_else()
do_something()

python运行时抱怨:

Traceback (most recent call last):
  File "/home/rahul/workspace/PyTest/func.py", line 94, in <module>
    do_somehting_else()
  File "/home/rahul/workspace/PyTest/func.py", line 91, in do_somehting_else
    if name == 10:
NameError: global name 'name' is not defined

要解决此问题,如果函数调用在您的控件中,请按正确的顺序执行它们。如果没有,请创建一个模块级别名称并直接在 def gamescreen():中访问它,就像您在 def buttonclick_gamescreen(事件)中所做的那样:。基本上,像这样:

global pressed

希望这会有所帮助:)。

答案 2 :(得分:0)

问题是在您检查pressed

的地方之前没有执行定义
def gamescreen():
    # ...
    canvas.bind("<Button-1>", buttonclick_gamescreen)  # You only attach callback
    # ...  "pressed" still not defined
    while cdtimer != 0:
        # ...
        if pressed == 8:  # you access "pressed" here
            # ...

在模块级别明确定义pressed,或明确调用buttonclick_gamescreen