"James Stroud" <[EMAIL PROTECTED]> wrote in message news:[EMAIL PROTECTED] | Beorn wrote: | > Consider this example: | > | > >>> def funcs(x): | > ... for i in range(5): | > ... def g(): return x + i | > ... yield g | > | > >>> [ fun() for fun in list(funcs(1)) ] | > [5, 5, 5, 5, 5] | > | > Whereas: | > | > >>> [ fun() for fun in funcs(1) ] | > [1, 2, 3, 4, 5]
| If this isn't classified as a bug, It is not, it is well-documented behavior. Still, suggestions for improvement might be considered. | Why would it be desirable for a generator to behave | differently in two different contexts. I have no idea. Each call of the generator function funcs behaves the same. It returns a generator that yields 5 identical copies of the inner function g. The multiple copies are not needed and only serve to confuse the issue. Changing funcs to return a generator that yields the *same* function (five times) gives the same behavior. def funcs(x): def g(): return x + i for i in range(5): yield g print [ fun() for fun in list(funcs(1)) ] print [ fun() for fun in funcs(1) ] >>> # when run [5, 5, 5, 5, 5] [1, 2, 3, 4, 5] What matters is the value of g's nonlocal var i (funcs' local var i) when the yielded function g is *called*. The difference between returning versus yielding an inner closure such as g is this. If g is returned, the outer function has terminated and the enclosed variable(s), i in this case, is frozen at its final value. If g is yielded, the enclosed i is *live* as long as the generator is, and its values can change between calls, as in the second print statement. | Should I import this to see how | many principles this behavior violates? ??? If you meant 'report' (on SF), please do not. Terry Jan Reedy -- http://mail.python.org/mailman/listinfo/python-list