1

I just learned closures and I discovered that:

from threading import Thread
from time import sleep

def call(time,f):
    def caller():
        sleep(time)
        f()
    Thread(target=caller).start()

def func():
    for i in range(1,6):
        call(i,lambda: print(i))

func()

And that code writes five '5' onto the screen. Thats amazing. And I understand that it is because of the same memory addresses. Now I want to know is there are any good and pythonic way of make that function write 1,2,3,4,5 instead of 5,5,5,5,5. For example you can do it in js by using let keyword.

1 Answers1

2

The issue is that you're not really creating a closure, you're just giving it the same lambda each time.

Instead you can return a function that binds the value of i:

from threading import Thread
from time import sleep

def call(time,f):
    def caller():
        sleep(time)
        f()
    Thread(target=caller).start()

def bind(i):
    return lambda: print(i)

def func():
    for i in range(1,6):
        call(i, bind(i))

func()

bind returns a function where the value of i is "closed over", or as you appropriately called it, a closure.

MatsLindh
  • 49,529
  • 4
  • 53
  • 84