-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

これらの2つのcurrent変数は同じものを参照していません。最初のものは関数のローカル変数ですwizintro。2番目はグローバル変数です。

別のエラーとは対照的に、この特定のエラーの理由は次の行です。

idx = pages.index(current) + dirn

。という名前の変数を参照していますcurrent。あなたはそれがだと言いましglobalたが、グローバルスコープでそれに値を割り当てたことはありません。だから、それは未定義です。したがって、例外が発生します。

行を削除するだけglobal currentで、2つの異なる関数のローカル変数を参照しますが、それでもおそらく必要なものではありません。同じ行で実質的に同じエラーが発生します。これで、ローカルスコープに値を割り当てずに使用しているローカル変数になりますが、それ以上のことはありません。

を外部スコープからmove参照することは明らかです。current

Python 3.xを使用している場合nonlocal currentは、おそらくそれが目的です。

そうでない場合は、いくつかのオプションがあります。

「可変のデフォルトパラメータ値」トリックを使用できます。currentたとえば、list1つの要素()のaに置き換えてから、追加のパラメータとして。current=[page1]に渡します。誰もデフォルトをオーバーライドしない限り、外部スコープの変数と同じ変数ではないにもかかわらず、同じへの参照であるという名前のローカル変数があり、同じ変数も同じです。(ローカル変数をクロージャにバインドするためのさまざまなトリックがあり、Scheme / Haskellなどのバックグラウンドから来た人々にとってより親しみやすいと感じるかもしれませんが、効果は同じです。)current=currentmovemovecurrentcurrent[0]

currentまたは、両方のスコープでグローバルを作成することもできます。

または、反対の方向に進みます。wizintroクラスに変換し、moveフレンドをメソッドにcurrent変換し、インスタンス変数に変換します。これは本当にあなたがここでやろうとしていることのようです。

于 2013-03-18T18:06:03.983 に答える
0

globalを使用して外部スコープから非グローバル変数を変更することはできません。グローバル (モジュール レベル) 変数を変更する場合にのみ使用できます。Python 3.x にはnonlocalそのための機能があります。ロジックを変更することを検討してください。

于 2013-03-18T18:08:01.723 に答える
0

あなたが抱えている問題はcurrent、がグローバル変数ではなく、wizIntro関数内のローカル変数であるためです。ネストされた関数moveはそれにアクセスしようとしますが、そのglobalステートメントはグローバル名前空間で値を見つけられません。これは、後でアクセスしようとすると、NameError.

Python 2 を使用している場合、ネストされた関数内から外側の関数の名前空間の変数にアクセスする適切な方法がありません。あなたができる最善のことは、 (最初​​に割り当てる前に)currentグローバルであると宣言することだと思います。wizIntroPython 3 ではnonlocal、現在の構造で機能するキーワードが導入されています (現在のglobalステートメントを置き換えるだけです。

于 2013-03-18T18:09:24.153 に答える