seeking deeper (language theory) reason behind Python design choice

Ian Kelly ian.g.kelly at gmail.com
Wed May 9 01:36:06 EDT 2018


On Tue, May 8, 2018 at 9:48 PM, Python <python at bladeshadow.org> wrote:
> On Tue, May 08, 2018 at 12:45:29AM +0000, Steven D'Aprano wrote:
>> since = in a statement on its own is not dangerous. People *almost never*
>> intend to write == for the side-effects only:
>
> Seriously?  I do this--not every day, but more than occasionally, not
> just in Python.
>
>     flag = (spam == arg)
> vs.
>     if spam == arg:
>         flag = True
>     else:
>         flag = False
>     if flag:
>         do_something()
>     else:
>         do_something_else()

As Chris pointed out, this is not an example of using == for side-effects only.

>>     # don't care whether they are actually equal or not
>>     # just want to call the __eq__ method for its side-effects
>>     spam == arg + 1
>>
>> Since that never happens in real life, there's no risk of accidentally
>> writing "spam = arg + 1" when you wanted "spam == arg + 1".
>
> I've always felt that this mentality was insulting to the programmer:
> "You're too stupid to get this right."  Sure, I've created that bug in
> other languages (or rather its inverse) but not since college.  You
> make it a few times, you go nuts debugging it, you learn what it is,
> you never do it again.
>
> And, this kind of thing is what code reviews are for--Python isn't so
> idiot-proof that you can get away without doing them for any
> non-trivial code--so (IMO) the language should not prevent you from
> doing useful things *simply* because you *might* make a mistake.

I do code reviews every day, and I doubt that I would actually notice
if one of them slipped in '=' where '==' was intended. Hopefully it
would be caught by unit testing though.

>  I'll
> give you an example that is both a case where Python's design choices
> make creating a bug easier, AND a case where allowing assignments to
> be expressions would save you.
>
>     flag = we_are_done()
>     while not flag:
>         # do some stuff
>         ...
>         if error_occured():
>             break
>         falg = we_are_done()
>     notify_user()
>    # flag will be checked again later, perhaps for error reporting


while True:
    if we_are_done():
        break
    # do some stuff
    ...
    if error_occurred():
        break
notify_user()


Fixed, using idiomatic Python and without needing to use assignment in
an expression.

> Here, a common programming pattern (prime the loop control variable)
> gets you in trouble, because the assignment happens in two places, and
> you mistyped one of them.  There's no syntax error, but your program
> will execute forever, unless you were already done on the first call
> to prime the flag, or an error occurs.  This is probably worse than
> the = vs. == error, because your brain tends to "autocorrect" certain
> kinds of spelling errors, whereas experienced programmers learn to
> look for (or avoid entirely) the assignment vs. comparison bug.  The
> error here is reasonably easy to spot, given the trivial nature of the
> example, but would likely be harder to spot in more complex code with
> longer, more meaningful variable names.
>
> This example also is a case FOR allowing assignments to be
> expressions.  If Python allowed them, you could rewrite this as:
>
>    while not (flag = we_are_done()):
>         ...
>         if error_occured():
>             break
>    notify_user()
>    # flag will be checked again later, perhaps for error reporting
>
> This COMPLETELY PREVENTS the spelling bug in the code above, since the
> assignment only happens in one place; and as a bonus it's less code.

Or just use an IDE with variable name autocompletion.



More information about the Python-list mailing list