[Python-Dev] PEP 572: Assignment Expressions

Tim Peters tim.peters at gmail.com
Wed Apr 18 12:38:26 EDT 2018


[Tim]
>> And, for some reason, I find this even worse:
>>
>>     while ((x, y) := func_returning_tuple())[1] is not None:
>>         ...
>>
>> The rub there:  I gave `y` a name but can't use it in the test?!
>>
>> And those are the same kinds of headaches I saw over & over in my own
>> "fancier" code:  stuff that's already perfectly clear would become
>> more obscure instead.

[Nick]
> Whereas I think:
>
>     while (s := func_returning_tuple())[1] is not None:
>         s = x, y
>         ...
>
> compares favourably with the loop-and-a-half version.

Obviously not, since it really needs to be

    x, y = s

instead ;-)

In context, I was looking for realistic cases in which assignment
expressions _fancier than_

    identifier ":=" expression

is a real improvement.  You found an improvement instead by
_replacing_ a "fancier than" instance with a plain-single-name target.
I already have lots of examples from real code where plain-single-name
target reads better to me.  I don't have any yet from real code where
something fancier does.

In this specific case, I find your rewriting about as readable as the
loop-and-a-half, except for the obvious drawback of the former:

> It does make the guarantee that "y is not None" harder to spot than it
> is in the loop-and-a-half version, though.

Over time, the functions in the real codes from which the example was
synthesized change, sometimes carrying more or less state in tuples.
When that happens, the original

    x, y  = s

will helpfully blow up (size mismatch in unpacking),  But, if the
tuple length increased, is it still the case that I want to test the
1'th component?  The test is now divorced from the unpacking.  I do
know that I'll still want to test the component I think of as being
"the 'y' component", and the loop-and-a-half version accommodates that
naturally.

Then again, I could switch to new-fanged namedtuples instead, and do

    while (s := func_returning_tuple()).y is not None:

to get the best of all worlds.


More information about the Python-Dev mailing list