[Python-ideas] PEP 572: Assignment Expressions (post #4)

Chris Angelico rosuav at gmail.com
Wed Apr 11 18:43:05 EDT 2018


On Thu, Apr 12, 2018 at 5:24 AM, Kirill Balunov <kirillbalunov at gmail.com> wrote:
> I find that I wrote very vague, so I'll try in response to my answer to add
> some specifics. In general, I find this idea missed in the language and
> thank you for trying to fix this! In my opinion it has only a meaning in
> certain constructions such as `while`, `if`, `elif` and maybe
> comprehensions\generators. As a general form "anywhere" it can be _useful_,
> but makes the code unreadable and difficult to perceive while giving not so
> much benefit. What I find nice to have:
>
> Extend while statement syntax:
>
>  while (input("> ") as command) != "quit":
>      print("You entered:", command)

What you're writing there is not truly an extension of the while
statement, but a special feature of an expression *within* the while
header. Syntactically, this "expr as name" notation must be able to be
combined with other operators (as in what you've written here), so it
isn't like the way the 'with' or 'import' statement specifically makes
a feature available as its own syntax.

> Extend ternary expression syntax:
>
> data = y/x if (f(x) as y) > 0 else 0

Again, this is doing further operations after the capturing, so it's
not like you can incorporate it in the syntax. You can't write:

expr2 if expr1 as NAME else expr3

and explain its semantics that way, because then you can't put the ">
0" part in anywhere.

So if, syntactically, this is a modification to expressions in
general, why restrict them to certain contexts? Why can't I lift the
condition out of the 'while' and give it a name?

while (input("> ") as command) != "quit":
# becomes #
cond = (input("> ") as command) != "quit"
print(cond)
while cond:

But I can't if this is magic in the 'while' statement. What do you
gain by forbidding it?

> I think that is all. And it seems to me that it covers 99% of all the
> use-cases of this feature. In my own world I would like them to make a local
> _statement_ binding (but this is certainly a very controversial point). I
> even like that this syntax matches the `with` an `except` statements syntax,
> although it has a different semantic. But I do not think that anyone will
> have problems with perception of this.

Statement-local names, controversial? You don't say!

I actually think the parallel with 'with' and 'except' works *against*
that version of the proposal, precisely because of the different
semantics (as you mention). The difference between:

except Exception as e:
except (Exception as e):

is significant and fairly easy to spot; as soon as you try to use 'e',
you'll figure out that it's the Exception class, not the instance that
got thrown. But in a 'with' statement?

with open(fn) as f:
with (open(fn) as f):

These will do the same thing, because Python's file objects return
self from __enter__. So do a lot of context managers. You can go a
VERY long way down this rabbit-hole, doing things like:

with (open(infile) as read and
        open(outfile, "w") as write):
    write.write(read.read())

In CPython, you likely won't notice anything wrong here. And hey, it's
backslash-free multi-line context management! In fact, you might even
be able to use this in *Jython* without noticing a problem. Until you
have two output files, and then stuff breaks badly. Thus I sought to
outright forbid 'as' in the expressions used in a 'with' or 'except'
statement. The problem doesn't exist with ':=', because it's clear
that the different semantics go with different syntax:

with open(fn) as f:
with f := open(fn):

And since there's no reason to restrict it, it's open to all contexts
where an expression s needed.

ChrisA


More information about the Python-ideas mailing list