Struggling with lexical scoping and for loops
The second approach may work with few changes:
for b in range(x): def helper_lambda(c, modifier): return lambda: current_instance.modify_attr(c, modifier) # removed event argument button = tk.Button(button_frame, text="<", command=helper_lambda(b, -1)) button.place(x=110, y=80 + 18 * b) button = tk.Button(button_frame, text=">", command=helper_lambda(b, 1)) button.place(x=150, y=80 + 18 * b)
However, you can use lambda
directly without the helper function:
for b in range(x): button = tk.Button(button_frame, text="<", command=lambda b=b: current_instance.modify_attr(b, -1)) button.place(x=110, y=80 + 18 * b) button = tk.Button(button_frame, text=">", command=lambda b=b: current_instance.modify_attr(b, 1)) button.place(x=150, y=80 + 18 * b)
This is a case where functools.partial
is a better option than a lambda expression.
from functools import partialfor b in range(x): button = tk.Button(button_frame, text="<", command=partial(current_instance.modify_attr, b, -1)) button.place(x=110, y=80 + 18 * b) button = tk.Button(button_frame, text=">", command=partial(current_instance.modify_attr, b, 1)) button.place(x=120, y=80 + 18 * b)
partial
receives the value of b
as an argument, rather than simply capturing the name b
for later use.