Urgh, we need this sorted out before Raymond can rewrite PEP 289 and present it to c.l.py... > [Samuele Pedroni] > > so this, if I understand: > > > > def h(): > > y = 0 > > l = [1,2] > > it = (x+y for x in l) > > y = 1 > > for v in it: > > print v > > > > will print 1,2 and not 2,3 > > That is what I had in mind, and that if the first assignment to "y" were > commented out, the assignment to "it" would raise UnboundLocalError. > > > unlike: > > > > def h(): > > y = 0 > > l = [1,2] > > def gen(S): > > for x in S: > > yield x+y > > it = gen(l) > > y = 1 > > for v in it: > > print v > > Yes, but like it if you replaced the "def gen" and the line following it > with: > > def gen(y=y, l=l): > for x in l: > yield x+y > it = gen() > > This is worth some thought. My intuition is that we *don't* want "a > closure" here. If generator expressions were reiterable, then (probably > obnoxiously) clever code could make some of use of tricking them into using > different inherited bindings on different (re)iterations. But they're > one-shot things, and divorcing the values actually used from the values in > force at the definition site sounds like nothing but trouble to me > (error-prone and surprising). They look like expressions, after all, and > after > > x = 5 > y = x**2 > x = 10 > print y > > it would be very surprising to see 100 get printed. In the rare cases > that's desirable, creating an explicit closure is clear(er): > > x = 5 > y = lambda: x**2 > x = 10 > print y() > > I expect creating a closure instead would bite hard especially when building > a list of generator expressions (one of the cases where delaying generation > of the results is easily plausible) in a loop. The loop index variable will > probably play some role (directly or indirectly) in the intended operation > of each generator expression constructed, and then you severely want *not* > for each generator expression to see "the last" value of the index vrlbl. Right. > For concreteness, test_generators.Queens.__init__ creates a list of rowgen() > generators, and rowgen uses the default-arg trick to give each generator a > different value for rowuses; it would be an algorithmic disaster if they all > used the same value. > > Generator expressions are too limited to do what rowgen() does (it needs to > create and undo side effects as backtracking proceeds), so it's not > perfectly relevant as-is. I *suspect* that if people work at writing > concrete use cases, though, a similar thing will hold. > > BTW, Icon can give no guidance here: in that language, the generation of a > generator's result sequence is inextricably bound to the lexical occurrence > of the generator. The question arises in Python because definition site and > generation can be divorced. So, do you want *all* free variables to be passed using the default-argument trick (even globals and builtins), or only those that correspond to variables in the immediately outer scope, or only those corresponding to function scopes (as opposed to globals)? n = 0 def f(): global n n += 1 return n print list(n+f() for x in range(10)) --Guido van Rossum (home page: http://www.python.org/~guido/)
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4