[Python-Dev] (name := expression) doesn't fit the narrative of PEP 20

Steven D'Aprano steve at pearwood.info
Thu Apr 26 03:56:28 EDT 2018


On Thu, Apr 26, 2018 at 03:31:13AM -0400, Terry Reedy wrote:
> On 4/25/2018 8:20 PM, Chris Angelico wrote:
> >On Thu, Apr 26, 2018 at 10:11 AM, Yury Selivanov
> ><yselivanov.ml at gmail.com> wrote:
> >>Just yesterday this snippet was used on python-dev to show how great the
> >>new syntax is:
> >>
> >>           my_func(arg, buffer=(buf := [None]*get_size()), size=len(buf))
> 
> What strikes me as awful about this example is that len(buf) is 
> get_size(), so the wrong value is being named and saved. 
> 'size=len(buf)' is, in a sense, backwards.

Terry is absolutely right, and I'm to blame for that atrocity. Mea 
culpa.

But Yury is misrepresenting the context in which I came up with that 
snippet. It was not "to show how great the new syntax is", but to try to 
give a *more realistic example of what we might right, instead of the 
toy example he had given:

Yuri claimed that 

    my_func(a=(b:=foo))

was "barely readable" and I responded:


    There's no advantage to using binding-expressions unless 
    you're going to re-use the name you just defined, and that
    re-use will give you a hint as to what is happening:

Alas, my spur of the moment example was crap, as you point out, but the 
point still stands: Yuri's example is mysterious, because there's a 
local variable b assigned to which doesn't seem to be used anywhere. It 
is either a mistake of some sort, simply poor code, or maybe b is used 
somewhere else in the function. Which seems poor style: if b is intended 
to be used elsewhere in the function, why not use normal assignment?

Using a binding expression is a hint that it is likely *intended* to 
only be used in the current expression, or block. That's not a rule 
that the compiler ought to enforce, but it is a reasonable stylistic 
idiom, like using ALLCAPS for constants. At least, that's my opinion.

So, crappy example or not, if I see a binding expression, that hints 
that the name used is needed in the current expression multiple times. 
It certainly should motivate me to look further ahead in the current 
expression to see where the newly defined variable is used next, and if 
it is only used once, to wonder if there has been some mistake.

Whereas a stand alone assignment doesn't really give any hint (apart 
from vertical proximity, which is a very poor hint) as to how often and 
where a variable is used.


-- 
Steve


More information about the Python-Dev mailing list