1

Windows 7x64 Python2.7

Pythonスレッド ソリューションのレキシカル クロージャーを自分のコードに適用しようとしています。for ループおよびレキシカル環境でのクロージャ

画像とサムネイルのペアのリストを確認し、サムネイルを表示します。ラベルをクリックすると、フル サイズの画像を含む新しい TopLevel が表示されます。

実際には、ImagePairs の最後の画像のみが表示されます。調べてみると、上に投稿したスレッドが見つかりましたが、それを自分の状況に正確に適用する方法がわかりません。

            row, col = 0, 0
            #create a frame for the row
            rowFrame = Frame(master)
            for image, thumb in ImagePairs:
                curLbl = Label(rowFrame, image=thumb)
                curLbl.grid(row=0, column=col, sticky='news')

                curLbl.bind('<Button-1>', lambda e:self.popImage(image))  #or curLbl.image

                col += 1
                if col >= 3:
                    rowFrame.grid(row=row)
                    #create a new frame, for the next row
                    rowFrame = Frame(master)
                    col = 0
                    row += 1

私は次のような関数を作ることを考えました

def func(img=img):
   return img

grid() と bind() の間のスペースに挿入しますが、画像が見つからないというエラーが発生します。それに合うようにコードを変更するにはどうすればよいですか?

4

1 に答える 1

4

image = imageラムダ自体にデフォルト値を追加できます。

for image, thumb in ImagePairs:
            curLbl = Label(rowFrame, image=thumb)
            curLbl.grid(row=0, column=col, sticky='news')
            curLbl.bind('<Button-1>', lambda e, image = image:self.popImage(image))  #or curLbl.image

の代わりにfuncデフォルト値を作成した場合、定義のアイデアも機能します。imageimg

def func(e, img = image):
    self.popImage(img)

覚えておくべき重要なことは、デフォルト値はラムダ (または関数) が定義された時点でバインドされるということです。

したがって、ループを通過するたびに、新しいラムダが独自のローカル変数で定義され、定義時にバインドされimageた独自のデフォルト値が設定されます。imageしたがって、ラムダが後で呼び出されると、権限imageがアクセスされます。

デフォルト値が指定されていない状況とは対照的です:imageはもはやラムダのローカル変数ではありません。ラムダが呼び出されると、Python は外側のスコープでラムダを探しに行きます。しかし、それまでに for ループが完了imageし、外側のスコープで の最後の値に設定されImagePairsます。これが、どのボタンを押しても同じ最後の画像を取得していた理由です。すべてのラムダが同じ variable の値にアクセスしていましたimage

于 2012-04-13T20:55:54.333 に答える