0

Python 3.3.0 で Tkinter を使用して単純なアプリケーションの GUI を構築しようとしています。一見すると間違っているように見えるちょっとしたプログラミングの癖に出くわしました。それ自体は問題ではありませんが(私の目的には影響していません)、Pythonic の方法では意味がありません。

ということで、以下がソースです。

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()

これを実行してボタンをクリックすると"Goodbye"、予想どおりウィンドウが閉じます...ただし、ここに問題があります。この簡略化されたバージョンのコードを実行すると、次のようになります。

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

foo()

>>> eggs
>>> eggs

hee必要に応じて、定義された in にアクセスしfoo()て新しいheeinを作成しませんbar()。defnonlocal heeの先頭に追加すると、出力は次のようになります。bar()

>>> eggs
>>> spam

予想通りでしょう。

それで、ここでの私の質問はroot、最初の例で最初に非ローカルであると宣言せずにオブジェクトを呼び出すことができるのはなぜですか?

4

1 に答える 1

0

Python スコープ規則の簡単な説明(「 Python チュートリアル」も参照) によると、オブジェクト名のスコープ解決は 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です。ここで、pi.barは で最初にオブジェクトをbar()探します。それが見つからない場合、オブジェクトが最初に宣言されている までスコープを絞り始めます。pibar()foo()pi

于 2013-08-11T20:58:21.640 に答える