python - How do lexical closures work? -
while investigating problem had lexical closures in javascript code, came along problem in python:
flist = [] in xrange(3): def func(x): return x * flist.append(func) f in flist: print f(2)
note example mindfully avoids lambda
. prints "4 4 4", surprising. i'd expect "0 2 4".
this equivalent perl code right:
my @flist = (); foreach $i (0 .. 2) { push(@flist, sub {$i * $_[0]}); } foreach $f (@flist) { print $f->(2), "\n"; }
"0 2 4" printed.
can please explain difference ?
update:
the problem is not i
being global. displays same behavior:
flist = [] def outer(): in xrange(3): def inner(x): return x * flist.append(inner) outer() #~ print # commented because causes error f in flist: print f(2)
as commented line shows, i
unknown @ point. still, prints "4 4 4".
python behaving defined. three separate functions created, each have closure of environment they're defined in - in case, global environment (or outer function's environment if loop placed inside function). problem, though - in environment, i mutated, , closures refer same i.
here best solution can come - create function creater , invoke that instead. force different environments each of functions created, different i in each one.
flist = [] in xrange(3): def funcc(j): def func(x): return x * j return func flist.append(funcc(i)) f in flist: print f(2)
this happens when mix side effects , functional programming.
Comments
Post a Comment