Twisted (or for loops ?) madness

Diez B. Roggisch deets at nospam.web.de
Mon Oct 15 06:28:10 EDT 2007


looping wrote:

> On Oct 15, 9:46 am, looping <kad... at gmail.com> wrote:
>> l = [ct1, ct2, ct3]
>> for c in l:
>>     d.addCallback(lambda result: c.compile())
>>
>> reactor.callLater(20, reactor.stop)
>> reactor.run()
>>
>> Output:
>>
>> Compile : *OBJECT 1*
>> <__main__.CompilerThread object at 0x00BAD030>
>> Start : *OBJECT 1*
>> Compiler result : *OBJECT 1* *OBJECT 1*
>> Compile : *OBJECT 3*
>> <__main__.CompilerThread object at 0x00CD9470>
>> Start : *OBJECT 3*
>> Compiler result : *OBJECT 3* *OBJECT 3*
>> Compile : *OBJECT 3*
>> <__main__.CompilerThread object at 0x00CD9470>
>> Start : *OBJECT 3*
>> Compiler result : *OBJECT 3* *OBJECT 3*
>>
>> OBJECT 3 run 2 times and OBJECT 2 never ?!?
>>
>> Any idea ? Maybe something related to Threads ?
>> Thanks for your help.
> 
> After further tests, it look like it is the lambda that cause the
> problem:
> -Adding a parameter result to compile(self, result)
> -Changing d.addCallback(lambda result: c.compile()) for
> d.addCallback(c.compile)
> 
> And everything run fine.
> 
> Why lambda doesn't work ? (variable scope problem ?)

Yes. When defined, the lambda inherits the surrounding scope - which
contains the name c, that is bound to the last instance of the iteration.

What you need to do is to introduce a scoped variable inside the lambda at
creation time - e.g. like this:

for a in 1,2,3:
   d.addCallback(lambda arg=a: work(a))

Diez



More information about the Python-list mailing list