Tuesday, December 15, 2009

try/for/while else... else what?

The Python language actually has support for else-clauses in some compound statements such as try, for and while.

So how do you use them?

I'll illustrate the for usage with an example:
def has_only_alpha_string(lst):
    for s in lst:
        if not s.isalpha():
            print '[{0}] contains non alphabetic character'.format(s)
            break
    else:
        print 'All strings contains only alphabetic characters'

lst = ['Hello', 'World!']

only_alpha_string(lst)
If lst is empty or exhausted the execution will continue in the else-clause. If the break is executed, the else-clause will not be executed. The same applies to while statements, the else is only executed if no break is executed within the while statement.

Note: It's valid to have a for/while-else without a break. In that case the else-clause will always be executed.

The first time I tried it I got it all wrong (before actually reading the documentation). I expected that the else-clause should be executed only if the list sequence was empty or exhausted, but it's the other way around.

What about try-else?

For me, at least, the try-else is probably a bit more intuitive.
try:
    f = None
    f = open('a_file', 'r')
except IOError as err:
    print err
else:
    print f.read()
finally:
    if f:
        print "Closing file..."
        f.close()
If the open call is successful the else-clause is executed and of course if the open call raises an IOError exception the else-clause isn't executed. Both open and read can raise IOError exceptions, the finally-clause will always be executed even if an exception occurs in the else-clause. In this particular case I'm only interested in catching the exception raised by open. If read raises an exception, it should be forwarded to the caller.

I could also write the code as following:
try:
    f = None
    f = open('a_file', 'r')
except IOError as err:
    print err
    # return or os.exit()

print f.read()
print "Closing file..."
f.close()
The problem with this solution is that file wouldn't be closed if read raises an exception.

Hope this post made the else-clause thing in combination with try/for/while more clear.


3 comments:

  1. to me it sounds like it should be called 'then' instead of 'else', for ... then not for ... else :P

    ReplyDelete
  2. Your right! While I was looking for more information about this topic I also found posts about the naming and that 'else' should have been 'then' instead.

    ReplyDelete
  3. I didn't know you could do that, this is going to be very useful. Thanks!

    ReplyDelete