Documentation, assignment in expression.

Steven D'Aprano steve+comp.lang.python at pearwood.info
Mon Mar 26 01:36:28 EDT 2012


On Sun, 25 Mar 2012 08:03:14 -0500, Tim Chase wrote:

> I think the complaint was backed by a bad example.  Perhaps a DB example
> works better.  With assignment allowed in an evaluation, you'd be able
> to write
> 
>    while data = conn.fetchmany():
>      for row in data:
>        process(row)

Yes, but why would you want to? Apart from making your code hard to read. 
Better written as:

while data = conn.fetchmany():  # THIS IS NOT A TYPO
    for row in data:
        process(row)


When you need to write a comment explaining that something isn't a typo, 
that's a good clue that you shouldn't do it *wink*

But seriously, assignment as an expression is a pretty major code-smell. 
Even when it's innocent, it should still fire off warning alarms, because 
how do you know if it's innocent or not until you've studied the code?

(Comments, like the above, are prone to get out of date with the code, 
and can't be entirely trusted.)

Python avoids this code smell by prohibiting assignment as an expression. 
Functional languages avoid it by prohibiting assignment. Other languages 
may choose to do differently. If all languages did exactly what C does, 
they'd all be C.

(I seem to recall a language that used a single = for both assignment and 
equality testing, guessing which one you meant from context. BASIC 
perhaps? Whatever it was, I'm pretty sure they regretted it.)


> whereas you have to write
> 
>    while True:
>      data = conn.fetchmany()
>      if not data: break
>      for row in data:
>        process(row)

Or even:

data = 'SENTINEL'  # Any true value will do.
while data:
    data = conn.fetchmany()
    for row in data:
        process(row)


There's no need to break out of the while loop early, because `for row in 
<empty>` is a null-op.




-- 
Steven



More information about the Python-list mailing list