2017-01-10 8 views
0

ラムダイベントハンドラでしばらく読んだら、本当に私を混乱させました。例えば私は、以下の2行のコードがあります。ラムダイベントハンドラが宣言されていない可能性がありますか?

b1 = Button(root,text="Show",command=(lambda e=ents :fetch(e))) 

root.bind("<Return>",(lambda event, e=ents : fetch(e))) 

エントをタプルのリストを返す関数です。 [("a",x),("b",y)]と言いますが、xyは、私の仕事を説明するためにエントリ(texbox)から取得しています。 フェッチはタプルの最初の行のために

def fetch(entries): 
    for entry in entries: 
     field = entry[0] 
     text = entry[1].get() 
     print ("%s: %s" %(field,text)) 

を出力シンプルな機能である、ラムダは何のイベント引数を取っていないと我々は結合の際にイベントを使用しながら、私たちは直接、コンテキスト( ents)を得ました。だから、なぜ我々はあるイベントでイベントを使用し、他のイベントでは使用しないのですか?

もう一つの問題は、なぜ我々は(この場合はeに)変数にリストを割り当てる必要がないのであれば、それはエラーを返しますので、直接そのよう

root.bind("<Return>",(lambda event,ents: fetch(ents)))

それを使用することはできません:<lambda>() missing 1 required positional argument: 'ents'

+1

2番目の質問では、 'e = ents'はデフォルト引数として関数引数' e'に変数entsの現在の値を代入しています。つまり、ラムダ関数が呼び出されたときに、その引数を指定する必要はありません。 – khelwood

答えて

2

commandボタンのパラメータがパラメータなしで呼び出されます。

イベントバインディングのハンドラは、1つのパラメータ(イベント自体)で呼び出されます。

両方のラムダのe=entsは、技術的にはパラメータですが、実際のパラメータをラムダに渡す必要はありません。それはラムダで使用するための値をキャプチャする単なる慣用​​的な方法です。 lambda: fetch(ents)のように簡単に書くことができます。二つのわずかな違い:

  1. e=ents値への以降の変更は無視され、ラムダが定義された時点でのentsの値をキャプチャします。ここでは関連性があるかもしれません。
  2. ラムダが呼び出されるたびにではなく、値を一度ルックアップする方が少し効率的です。これは完全に無関係ですが、ラムダが何百万回も呼び出される場合の最適な最適化であるかもしれません。
+0

ありがとう、これは完全に私の質問に答え、良い一日を –

関連する問題