4

(正如“作业”标签所示,这是计算机科学中一个大项目的一部分。)

我在写危险!使用 tkinter 在 Python 中进行模拟,我在按钮中使用 lambda 函数时遇到了一个大问题。假设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功能都使用最后一个按钮的原因。

如果您将 lambda 定义为采用一个具有默认值的参数,则默认值在定义 lambda 时确定(并固定。Nowb是 的局部变量lambda,当不带参数调用 lambda 时,Python 设置b为默认值,该默认值很高兴根据需要设置为各种不同的按钮。

于 2012-06-12T21:52:27.250 回答
0

如果你用函数工厂替换 lambda 表达式,它会让你更有表现力。(假设您要多次调用它)。这样你就可以在以后进行分配、添加更复杂的逻辑等,而不必处理 lambda 的限制。

例如:

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

给定一个 input bbutton_factory返回一个可调用的函数,该函数()返回你想要的。唯一的区别是你可以做作业等。

尽管它最初可能会占用更多的代码行,但它会在以后为您提供更大的灵活性。(例如,您可以将计数器附加到 bsel 并能够计算选择特定问题的次数等)。

它还有助于自省,因为您可以使每个文档字符串清楚地识别它与哪个问题相关联,等等。

于 2012-06-12T22:14:46.650 回答