[Python-Dev] PEP 572: Assignment Expressions (original) (raw)

Steven D'Aprano steve at pearwood.info
Sat Apr 21 12:31:53 EDT 2018


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.

This.

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.

Indeed.

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.

-- Steve



More information about the Python-Dev mailing list