4

(「宿題」タグが示すように、これはコンピュータサイエンスの大きなプロジェクトの一部です。)

ジェパディを書いています!tkinterを使用したPythonでのシミュレーションで、ボタンでのラムダ関数の使用に関して大きな問題が発生しています。と仮定root = Tk()categoriesて、リストです。

# Variable to keep the buttons
root._buttons = {}

# Display headers on top of page
for i in range(5):
    # Get category name for display in main window
    name = categories[i]
    b = Label(root, text=fill(name.upper(), 10), width=18, height=3,\
        bg="darkblue", fg="white", font=("Helvetica bold", "", 11))
    b.grid(row=0, column=i)

    # Create list of buttons in that variable (root._buttons)
    btnlist = [None]*5

    # Display individual questions
    for j in range(5):

        # Make a button for the question
        b = Button(root, text="$" + str(200 * (j+1)), width=8, height=1,
            bg="darkblue", fg="orange", font=("Impact", "", 30))
        b.cat = name
        b.value = 200 * (j + 1)
        b.sel = lambda: select(b.cat, b.value)

        # Add callback event to button
        print(b.cat, b.value, b.sel)
        b.config(command=b.sel)

        # Add button to window
        b.grid(row=j+1, column=i)

        # Append to list
        btnlist[j] = b

    root._buttons[categories[i]] = btnlist

すべてのコードについては、私の小さなコードビューア(作成中です!)を参照してください。

ボード上のlambda: select(b.cat, b.value)いずれかのボタンをクリックすると、常にボード上の最後のボタンに移動するため、問題が発生しているように見える場所です。私は他のアプローチを試しましたが、残念ながらすべてを使用しlambdaていますが、を含まないアプローチは見たことがありませんlambda

4

2 に答える 2

9

変化する

lambda: select(b.cat, b.value)

lambda b = b: select(b.cat, b.value)

元のコードでは、は;bのローカル変数ではありません。lambdaスコープを囲んでいます。for-loopが完了すると、b最後の値が保持されます。そのため、lambdaすべての関数で最後のボタンが使用されます。

デフォルト値で1つの引数を取るようにラムダを定義すると、ラムダが定義されたときにデフォルト値が決定(および固定)されます。これbはのローカル変数でありlambda、ラムダが引数なしで呼び出されると、Pythonbはデフォルト値に設定され、必要に応じてさまざまなボタンに設定されます。

于 2012-06-12T21:52:27.250 に答える
0

ラムダ式を関数ファクトリに置き換えると、より表現力豊かになります。(これを複数回呼び出すと仮定します)。そうすれば、ラムダの制限に対処することなく、後で割り当てを行ったり、より複雑なロジックを追加したりできます。

例えば:

def button_factory(b):
    def bsel():
        """ button associated with question"""
        return select(b.cat, b.value)
    return bsel

入力が与えられると、あなたが望むものを正確に返すbbutton_factory呼び出し可能な関数を返します。()唯一の違いは、割り当てなどを実行できることです。

最初はコードの行数が増える可能性がありますが、後で柔軟性が高まります。(たとえば、bselにカウンターを取り付けて、特定の質問が選択された回数を数えることができます)。

また、各docstringに、関連付けられている質問などを明確に識別させることができるため、内省にも役立ちます。

于 2012-06-12T22:14:46.650 に答える