On Fri, 13 Jul 2012 19:31:24 -0700, rusi wrote: > Consider the following > > def foo(x): > i = 100 > if x: > j = [i for i in range(10)] > return i > else: > return i
A simpler example: def foo(): i = 100 j = [i for i in range(10)] return i In Python 3, foo() returns 100; in Python 2, it returns 9. > In python 2 two different 'i's could be returned. In python3 only one i > can be returned. > One could call it dynamic binding. One could also call it a tractor, but it isn't either of those things. The difference is whether or not list comprehensions create their own scope. In Python 2, they don't; in Python 3, they do. Personally I don't have an opinion as to which is better, but in neither case does this have any thing to do with lexical versus dynamic binding. > Evidently Guido thinks it a bug which is why he changed it. It was a case that either list comps be changed to *not* expose their loop variable, or generator expressions be changed *to* expose their loop variable. The Python 2 situation where list comps and gen expressions have opposite behaviour was unfortunate. > The leakage of i in the OPs question is the same kind of bug. Not at all. The OP was *deliberately* creating a closure using i -- under those circumstances, it would be a bug if i *didn't* leak. The OP's gotcha was: 1) he expected the closure to use early binding, where i in each function was bound to the value of i in the enclosing scope at the moment the function was defined; 2) but Python actually uses late binding for closures, where the value of i in each function is set to the value of i in the enclosing scope when the function is called. As far as I can tell, Python always uses late binding for scopes; the only time it does early binding is for default values of function parameters. -- Steven -- http://mail.python.org/mailman/listinfo/python-list