0

It seems the the question has already been asked here :

but I did not understand the answers. Here is an other code example of the same question :

How to understand the scope in a for loop ?

[edit]my 'orient' function is defined like this:[/edit]

orient = lambda snake, direction: snake.changeDirection(direction)

I tried assigning tkinter bindings with this loop :

for player in Parameters.players:
    snake = self.snakes[player]
    self.root.bind(bindings[player]['up'], lambda event : orient(snake, Direction.N))
    self.root.bind(bindings[player]['left'], lambda event : orient(snake, Direction.W))
    self.root.bind(bindings[player]['down'], lambda event : orient(snake, Direction.S))
    self.root.bind(bindings[player]['right'], lambda event : orient(snake, Direction.E))

but the two bindings were assigned to the last snake

So i tried to do the loop "manually" :

player1 = Parameters.players[0]
snake1 = self.snakes[player1]
self.root.bind(bindings[player1]['up'], lambda event : orient(snake1, Direction.N))
self.root.bind(bindings[player1]['left'], lambda event : orient(snake1, Direction.W))
self.root.bind(bindings[player1]['down'], lambda event : orient(snake1, Direction.S))
self.root.bind(bindings[player1]['right'], lambda event : orient(snake1, Direction.E))

player2 = Parameters.players[1]
snake2 = self.snakes[player2]
self.root.bind(bindings[player2]['up'], lambda event : orient(snake2, Direction.N))
self.root.bind(bindings[player2]['left'], lambda event : orient(snake2, Direction.W))
self.root.bind(bindings[player2]['down'], lambda event : orient(snake2, Direction.S))
self.root.bind(bindings[player2]['right'], lambda event : orient(snake2, Direction.E))

and it worked (each snake had his bindings)

How is the lambda function actually created ? Why does it "captures" the variable and so gets overwritten instead of keeping its value ?

Hugo Trentesaux
  • 1,584
  • 1
  • 16
  • 30

1 Answers1

0

The final code is :

orient = lambda snake, direction: snake.changeDirection(direction)
for player in Parameters.players:
    snake = self.snakes[player]
    self.root.bind(bindings[player]['up'], lambda event, snake=snake : orient(snake, Direction.N))
    self.root.bind(bindings[player]['left'], lambda event, snake=snake : orient(snake, Direction.W))
    self.root.bind(bindings[player]['down'], lambda event, snake=snake : orient(snake, Direction.S))
    self.root.bind(bindings[player]['right'], lambda event, snake=snake : orient(snake, Direction.E))

Notice the "snake=snake" in lambda definition.

Explanation here : Creating functions in a loop

Hugo Trentesaux
  • 1,584
  • 1
  • 16
  • 30