[Python-Dev] PEP 572: Assignment Expressions
Chris Angelico
rosuav at gmail.com
Fri Apr 20 22:30:36 EDT 2018
On Sat, Apr 21, 2018 at 11:38 AM, Anthony Flury via Python-Dev
<python-dev at python.org> wrote:
> I am entirely new to this list, but if I can I would like share my comments
> :
>
> * I do think this proposal <target> := <value> has merit in my
> opinion; it does make some code more readable.
>
> * I think readability is only improved if :
There's that word "readability" again. Sometimes I wish the Zen of
Python didn't use it, because everyone seems to think that "readable"
means "code I like".
> * The current expectations of how comprehensions work should also be
> honored; I don't claim to have fully followed all of the discussions
> around this, but it seems to me that comprehensions work in a
> particular way because of a concerted effect (especially in Python
> 3) to make them that way. They are self contained and don't leak
> values in their containing scope. Similarly I think that setting
> variables within a comprehension is just for the benefit of readable
> code within the comprehension - i.e. :
>
> stuff = [[y, x/y] for x in range(5) for y in [f(x)]]
>
> can become :
>
> stuff = [[y := f(x), x/y] for x in range(5)]
>
> So - overall from me a conditional +1 - conditions as above; if they are not
> possible then -1 from me.
Perfectly self-contained. They do everything in their own scope.
Except ... except that they don't.
$ python3.7
Python 3.7.0a4+ (heads/master:95e4d58913, Jan 27 2018, 06:21:05)
[GCC 6.3.0 20170516] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> class X:
... x = ["spam", "ham"]
... print(["1: "+x for x in x])
... print(["2: "+x for _ in range(1) for x in x])
...
['1: spam', '1: ham']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 4, in X
File "<stdin>", line 4, in <listcomp>
UnboundLocalError: local variable 'x' referenced before assignment
>>> class Y:
... prefix = "3: "
... print([prefix + x for x in ["spam", "ham"]])
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in Y
File "<stdin>", line 3, in <listcomp>
NameError: name 'prefix' is not defined
Introducing expression assignments will make these oddities even more
obvious. You'd be able to demonstrate things like this at function
scope, not just with a class. But the oddities are there, and they are
inherent to the current definition of a comprehension. That's why the
changes are being recommended. They will simplify the peculiarities of
comprehensions, make them far closer to a naive transformation into
longhand, and extremely close to a non-naive-but-still-simple
transformation into longhand.
ChrisA
More information about the Python-Dev
mailing list