On Tue, May 8, 2018 at 9:48 PM, Python <pyt...@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. -- https://mail.python.org/mailman/listinfo/python-list