[Python-ideas] A comprehension scope issue in PEP 572
steve at pearwood.info
Tue May 8 14:19:32 EDT 2018
On Tue, May 08, 2018 at 01:28:59PM -0400, Juancarlo Añez wrote:
> So the way I envision it is that *in the absence of a nonlocal or global
> > declaration in the containing scope*, := inside a comprehension or genexpr
> > causes the compiler to assign to a local in the containing scope, which is
> > elevated to a cell (if it isn't already). If there is an explicit nonlocal
> > or global declaration in the containing scope, that is honored.
> This seems to be getting awfully complicated. Proof? Try to write the docs
> for the proposed semantics.
Okay, I'll bite. I don't know why you think its complicated: it is
precisely the same as ordinary ``=`` assignment scoping rules. It is
comprehensions that are the special case.
* * *
The binding expression ``<name> := <value>`` evaluates the right hand
side <value>, binds it to <name>, and then returns that value.
Unless explicitly declared nonlocal or global (in which case that
declaration is honoured), <name> will belong to the current scope, the
same as other assignments such ``name = value``, with one difference.
Inside comprehensions and generator expressions, variables created with
``for name in ...`` exist in a separate scope distinct from the usual
local/nonlocal/global/builtin scopes, and are inaccessible from outside
the comprehension. (They do not "leak".) That is not the case for those
created with ``:=``, which belong to the scope containing the
comprehension. To give an example:
a = 0
x = [b := 10*a for a in (1, 2, 3)]
assert x == [10, 20, 30]
assert a = 0
assert b = 30
> I don't understand why we went so astray from the original requirements,
> which could all be met by having `if` and `while` accept `as` to bind an
> expression to a variable that would be local to the structured statement.
That is not the original motivation for binding expressions. The
original requirements were specifically for comprehensions.
This is hardly the only time that something similar has been raised.
More information about the Python-ideas