[Python-Dev] PEP 572: Assignment Expressions

Ethan Furman ethan at stoneleaf.us
Mon Apr 23 18:15:37 EDT 2018


On 04/23/2018 03:04 PM, Tim Peters wrote:
> [Ethan Furman <ethan at stoneleaf.us>]
>> So I really like being able to make the assignment in the expression, but I
>> have a really hard time parsing it with the name first.
>>
>> ...
>>
>> On the other hand, if it were using the "as" keyword:
>>
>> if (x - xbase as diff) and (gcd(diff, n) as g) > 1:
>>      return g
>>
>> I would parse as:
>>
>>    if
>>      x - x_base
>>      as diff
>>    and
>>      gcd(diff, n)
>>      as g
>>    > 1:
>>        return g
>>
>> For me at least, the last is much more readable.  Thinking about it some
>> more, the problem (or maybe just my problem) is that I see an "if" or
>> "while" and the I look for the thing that is True or False, and using the
>> ":=" syntax the first thing I see is a placeholder for a result that doesn't
>> exist yet, making me constantly scan backwards and forwards to put all the
>> pieces in the correct place.
>>
>> With "as", it just flows forwards.
>
> I can read it fine either way, and don't much care.  A possible
> advantage of an "as" operator is that its precedence could be set to
> bind just a tad stronger than comparisons (which include "is" and "is
> not" in Python), and then, e.g.,
>
>      if f() as result is not None:
>          do something with result
>
> could work as intended.  So long as people can't get "assignment
> _statements_" out of their heads,
>
>      if result := f() is not None:
>
> groups instead as
>
>      if result := (f() is not None):
>
> which would almost never be _intended_.  Maybe spelling it "as"
> instead could break that.
>
> However, against "as" is that its current use in "with" statements
> does something quite different:
>
>      with f() as name:
>
> does not bind the result of `f()` to `name`, but the result of
> `f().__enter__()`.  Whether that "should be" fatal, I don't know, but
> it's at least annoying ;-)

"as" does something slightly different in each of its current incantations, but the one thing that they all have in 
common is taking some thing on the left and giving it the name on the right:

- imports -> thing on left gets name on right
- exceptions -> exception that matches class on left gets name on right
- with -> result of left.__enter__() gets name on right

I see very little harm in adding

- expression-binding -> eval(thing on left) gets name on right

--
~Ethan~



More information about the Python-Dev mailing list