Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/288.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 3.3-函数内部的Tkinter对象访问_Python_Tkinter_Python 3.3 - Fatal编程技术网

Python 3.3-函数内部的Tkinter对象访问

Python 3.3-函数内部的Tkinter对象访问,python,tkinter,python-3.3,Python,Tkinter,Python 3.3,我正试图在Python3.3.0上使用Tkinter为一个简单的应用程序构建GUI。 我偶然发现了一个小小的编程怪癖,乍一看似乎是错误的。虽然这本身不是一个问题(它不会影响我的目标),但从一个蟒蛇式的角度来看,这是没有意义的 因此,以下是来源: from tkinter import * from tkinter import ttk def foo(): def bar(): root.destroy() root = Tk() mainframe =

我正试图在Python3.3.0上使用Tkinter为一个简单的应用程序构建GUI。 我偶然发现了一个小小的编程怪癖,乍一看似乎是错误的。虽然这本身不是一个问题(它不会影响我的目标),但从一个蟒蛇式的角度来看,这是没有意义的

因此,以下是来源:

from tkinter import *
from tkinter import ttk

def foo():
    def bar():
        root.destroy()
    root = Tk()
    mainframe = ttk.Frame(root).grid(column=0, row=0)
    ttk.Button(mainframe,text="Goodbye",command=bar).grid(column=1, row=1)
    root.mainloop()

foo()
运行此操作并单击“再见”按钮将按预期关闭窗口。。。然而,问题就在这里。如果我运行此简化版本的代码:

def foo():
    def bar():
        hee = "spam"
    hee = "eggs"
    print(hee)
    bar()
    print(hee)

foo()

>>> eggs
>>> eggs
我没有访问
foo()
中定义的
hee
,也没有在
bar()
中创建一个新的
hee
。如果现在将
非本地hee
添加到
条()的开头,则输出:

>>> eggs
>>> spam
这将是预期的结果

因此,我这里的问题是,为什么在第一个示例中,我能够调用
根对象而不首先声明它为非本地对象?

,因为根据(另请参见)对象名称范围解析符合LEGB规则(本地、封闭函数、全局、内置)

话虽如此,以下示例举例说明了该规则:

class ni:
    bar = "hello"

def foo():
    pi = ni()
    def bar():
        pi.bar = "eggs"
    pi.bar = "spam"
    print(pi.bar)
    bar()
    print(pi.bar)

ni.bar

>>> hello

foo()

>>> spam
>>> eggs

此代码与简化版本代码之间的主要区别在于显式分配了名为
hee
的变量。这里,
bar()
中的
pi.bar
首先在
bar()
中查找
pi
对象。没有找到它,它开始向下延伸到
foo()
,在这里首先声明
pi
对象。

可能重复@Eric Thank。读完后,我明白了这个问题。因为在简化代码中,我显式声明了一个变量,而在实际示例中,我从先前声明的对象访问了一个属性,因此我遵循了LEGB范围规则。假设我没有在
bar()
上声明另一个根对象,它的作用域应该是在
foo()
上声明的根对象。