[Python-ideas] A comprehension scope issue in PEP 572

Steven D'Aprano 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.

https://mail.python.org/pipermail/python-ideas/2018-February/048971.html

This is hardly the only time that something similar has been raised.


-- 
Steve


More information about the Python-ideas mailing list