[Tutor] Minesweeper the return

Danny Yoo dyoo at hkn.eecs.berkeley.edu
Tue Jul 19 01:10:51 CEST 2005



On Mon, 18 Jul 2005, Alberto Troiano wrote:


> I'm trying to create the buttons dinamically (that's not a problem) the
> problem is wherever I click the hello function returns the last button I
> created. I know that the problem is in the lambda part and that the variable
> i (the one I change the value within the for) but I don't how to fix it


Hi Alberto,

Ah, this one comes up a bit.  *grin*  Let's look at the code:

######
for i in range(self.fil):
    for j in range(self.col):
        self.buttonmatrix[i][j]=Button(root,width=1,height=0,
                                       command=lambda: self.hello(i,j))
######

The issue is that all the dynamically generated functions are using the
same 'i' and 'j' variables.  The big issue is that, in Python, for-loops
rebind the iterating variable name to different values, and that's what's
causing the issue.


Instead of using lambda directly, try something like this:

######
def make_hello(x, y):
    def new_hello_function():
        self.hello(x, y)
    return new_hello_function

for i in range(self.fil):
    for j in range(self.col):
        self.buttonmatrix[i][j]=Button(root,width=1,height=0,
                                       command=make_hello(i, j))
######


There's some subtle lexical-binding stuff going on there, so if you'd
like, we can talk about this more.  If you're familiar with another
programming language with lexical scope (like Scheme), we can talk about
in terms of that language too.


Hope this helps!



More information about the Tutor mailing list