While in theory this is useful, it's one of the least intuitive parts of python for me. I avoid them whenever possible because I feel "else" conveys the intent very poorly. (And I've been writing python for years.)
Raymond Hettinger, one of the main Python devs, advises that the "else" in this situation should mentally be thought of as "notfound".
This badly named else is reminiscent of the "result forms" in Lisp loops like `dolist`, `do` or `loop`.<p><pre><code> (loop for x below 10
finally (princ "iterated over everything, ") (princ "indeed"))
</code></pre>
But, of course, these Lisp loops have a result value, and the result forms are an "implicit progn" which produces that value.
Not only it is not very intuitive, I also find it to hurt the linearity of code. The code which will be executed after the loop ends depends on how the loop ended. break statement is usually a glorified but mostly harmless go to, but I think Python's go to statement isn't so harmless as it adds complexity but doesn't have big benefits.<p>But, I do think that the else clause on try\except blocks is less harmful. It is less harmful because the control flow complexity of exceptions handling is already there on the catch clause, so while exceptions <i>does</i> add big control flow changes, the addition of the else clause causes a relative minor change on the linearity of code (as it is already broken by catch: clause.)
I always strongly discourage the use of things like this construct in any language.<p>A language is meant to be read not just written. A non-expert python programmer who encounters this will be confused.
Created an account to point out this gem by Guido himself that makes use of this and the fact that python variables are not scoped inside for loops:<p><a href="https://github.com/aosabook/500lines/blob/master/crawler/crawling.py#L100" rel="nofollow">https://github.com/aosabook/500lines/blob/master/crawler/cra...</a>
For me, the optional else on for loops isn't nearly as mentally destabilizing as the optional else on try-except blocks. An ex-employee used to <i>love</i> doing that:<p><pre><code> try:
None.doit()
except Exception as e:
logger.exception('Nope')
else:
# now what?
pass</code></pre>
Also known as "Dijkstra's loop" to give credit where credit is due. Only other language I know that has it though is Oberon (and that just introduced it in a pretty <i>recent</i> update)
Might be worth while looking at the video below for more Pythonic gems like this one.<p><a href="https://www.youtube.com/watch?v=OSGv2VnC0go" rel="nofollow">https://www.youtube.com/watch?v=OSGv2VnC0go</a>
This is all in Jeff Knupp's Writing Idiomatic Python:<p><a href="http://www.jeffknupp.com/blog/2012/10/04/writing-idiomatic-python/" rel="nofollow">http://www.jeffknupp.com/blog/2012/10/04/writing-idiomatic-p...</a><p>Many so-called Python Idioms are really non-intuitive and I don't really appreciate.