1

Consider the following code:

from threading import Thread

def foo(s):
   print(s)

d = {}
for s in ["a", "b"]:
   fun = lambda: foo(s)
   d[s] = Thread(target=fun)

[worker.start() for worker in d.values()]

I would expect that the lambda expression can not be changed after it got constructed, hence one of the threads needs to print an a, but that is not happening. Both threads are printing b. What IS happening here? What needs to be changed to have workload a included?

Tomerikoo
  • 18,379
  • 16
  • 47
  • 61
Harald Thomson
  • 730
  • 2
  • 8
  • 18
  • 1
    "I would expect that the lambda expression can not be changed after it got constructed" <- It does not. What changes is where the name `s` points to. After the loop `s = 'b'`. – timgeb Oct 20 '21 at 12:06
  • 1
    You would see the same behavior with "normal" functions btw. Put a `def fun(): foo(s)` inside the loop to see for yourself. – timgeb Oct 20 '21 at 12:11
  • 1
    ... And also without threads... – Tomerikoo Oct 20 '21 at 12:11
  • 1
    It does! Thank you very much. The solution is to change the lambda too `fun = lambda s=s: foo(s)` This way the name `s` is not reused from the outer scope. – Harald Thomson Oct 20 '21 at 12:12

0 Answers0