Tuesday, April 05, 2005

how well do you know python, part 2

An easy one today:
import os, threading

def foo(s):
    print s

for dir in os.listdir(os.getcwd()):
    threading.Thread(target=lambda: foo(dir)).start()
What bug may cause this to print something other than the contents of the current directory?

9 comments:

Ian Bicking said...

I feel like it's too soon to just answer straight out before other people try... how about...

print "Yrg'f fnl bf.yvfgqve(pjq)==['n', 'o']. Ba gur svefg eha guebhtu gur sbe ybbc, qve=='n', naq gur guernq vf fgnegrq. Vs nsgre gur guernq vf fgnegrq, ohg orsber vg trgf gb vaibxr sbb(qve) gur qve inevnoyr vf frg gb 'o' (orpnhfr gur ybbc vf eha gur frpbaq gvzr) gura sbb('o') jvyy or pnyyrq naq lbh'yy frr 'o\\ao\\a'".decode('rot13')

Jonathan Ellis said...

Exactly.

Thomas Hervé said...


for dir in os.listdir(os.getcwd()):
threading.Thread(target=foo, args=(dir,)).start()


Is the right way to do it ? Then dir would be evaluated at the Thread creation.

Jonathan Ellis said...

That's probably the best way, yes.

Gustavo Niemeyer said...

There's another common idiom which is doing something like:

lambda dir=dir: foo(dir)

OTOH, in this case there's already a standard way of passing arguments, as shown above.

Anonymous said...

lamdba is evil.

using threading for output is a friend of lambda.

Harald Armin Massa notonblogger

Anonymous said...

lambda is GOD!

How else would we say:

total_size = reduce( os.listdir(os.getcwd()), lambda a,x: a+os.stat(x).st_size,0 )

short, clear, and to the point

Theran said...

total_size = sum([ os.stat(x).st_size for x in os.listdir(os.getcwd())])

I like lambda too, but the non-lambda version is much clearer.

Theran said...

Shouldn't the lambda expression close over the current value of dir?