On 2006-04-21, Alexis Roda <[EMAIL PROTECTED]> wrote: > Ben C escribió: >> On 2006-04-21, Ben C <[EMAIL PROTECTED]> wrote: >> Having said that, I attempted to confirm this using def rather than >> lambda, and encountered something I cannot explain at all-- it appears >> that the functions are getting redefined whenever they are called, to >> effect a kind of "dynamic scoping" behaviour. I would appreciate any >> explanation anyone can give of this: >> >> fns = [] >> for y in range(2): >> def fn(): >> yy = y # exactly the same with yy = int(y) >> print "defining fn that returns", yy >> return yy >> print "Appending at", y >> print fn, fn() >> fns.append(fn) > > > yy = y does assign y's current value (current == fn call time, not fn > definition time). To return 0 and 1 as expected you should create a > "different/private" y for every fn's definition. > > ---------------------------------------- > > fns = [] > for y in range(2): > def fn(y=y): > yy = y > print "defining fn that returns", yy > return yy > print "Appending at", y > print fn, fn() > fns.append(fn) > > > ----------------------------------------
Yes; the difficulty is that the body of the function is executed (obviously) every time you call it. The body of the function reads y which is a global variable and has whatever value it has at the time. The parameters are the only part of a function definition where you get to write some code that initializes things in the function's "frame" when the function is defined rather than when it's called. I got confused because I was thinking of yy = y in the body of fn's definition as an initialization, not as an assignment. In other languages it's possible to distinguish, but not in Python. Really this is what classes are for in Python: def f(x): return x * x class fn(object): def __init__(self, y): # "define-time" things are here self.y = y def __call__(self, x): # "call-time" things are here return f(x) * self.y fns = [fn(i) for i in range(1, 10)] for f in fns: print f(1) is I think quite a good way to do this. -- http://mail.python.org/mailman/listinfo/python-list