On Sat, Apr 21, 2018 at 03:44:48PM +0000, David Mertz wrote:

> It feels very strange that the PEP tries to do two almost entirely
> unrelated things. Assignment expressions are one thing, with merits and
> demerits discussed at length.
> But "fixing" comprehension scoping is pretty much completely orthogonal.


> Sure, it might be a good idea. And yes there are interactions between the
> behaviors. However, trying to shoehorn the one issue into a PEP on a
> different topic makes all of it harder to accept.


*And* harder to understand.

As I see it, we ought to just decide on the semantics of assignment- 
expressions as they relate to comprehensions: do they bind to the 
comprehension scope, or the local scope? I prefer the second, for the 
reasons I stated earlier.

A third (slightly more complex) choice would be that they remain bound 
to the comprehension (like the loop variable) but they are initialised 
from any surrounding scope. I'd be happy with that as a "best of both 
worlds" compromise:

    # don't leak from comprehensions
    x = 1
    [(x := y+1) for y in items if x%2 == 0]
    assert x == 1

    # but still support running totals and similar use-cases
    total = 0
    [(total := total + y) for y in items]

    # and you can still get UnboundLocalError
    del total
    [(total := total + y) for y in items]  # total has no initial value

This is not entirely unprecedented in Python: it is analogous 
(although not identical) to binding default values to parameters:

    def running_total(items, total=total):
        # Here total is local to the function, but the default
        # is taken from the surrounding scope.

Cleaning up the odd interactions involved in comprehensions could be 
done separately, or later, or not at all. After all, this PEP isn't 
*introducing* those oddities. As Chris' earlier examples show, they 
already exist.

Python-Dev mailing list

Reply via email to