11

In Python the try statement supports an else clause, which executes if the code in try block does not raise an exception. For example:

try:
  f = open('foo', 'r')
except IOError as e:
  error_log.write('Unable to open foo : %s\n' % e)
else:
  data = f.read()
  f.close()

Why is the else clause needed? Can't we write the above code as follows :

try:
  f = open('foo', 'r')
  data = f.read()
  f.close()
except IOError as e:
  error_log.write('Unable to open foo : %s\n' % e)

Won't the execution proceed to data = f.read() if open does not raise an exception?

Honest Abe
  • 8,430
  • 4
  • 49
  • 64
John
  • 131
  • 4

4 Answers4

14

The difference is what happens if you get an error in the f.read() or f.close() code. In this case:

try:
  f = open('foo', 'r')
  data = f.read()
  f.close()
except IOError as e:
  error_log.write('Unable to open foo : %s\n' % e)

An error in f.read() or f.close() in this case would give you the log message "Unable to open foo", which is clearly wrong.

In this case, this is avoided:

try:
  f = open('foo', 'r')
except IOError as e:
  error_log.write('Unable to open foo : %s\n' % e)
else:
  data = f.read()
  f.close()

And error in reading or closing would not cause a log write, but the error would rise uncatched upwards in the call stack.

kaspermoerch
  • 16,127
  • 4
  • 44
  • 67
Lennart Regebro
  • 167,292
  • 41
  • 224
  • 251
  • 1
    Thanks Lennart. That was very clear ! :). So, why dont we see the else clause for try in other languages like say Java ? :) – John Jan 29 '11 at 10:01
  • 11
    @John: Because they aren't as good as Python? :-) – Lennart Regebro Jan 29 '11 at 10:05
  • If you're only expecting errors on the `open` call, the `read` and `close` calls didn't belong in the `try` block in the first place; just check if `f` is not null prior to reading from it via another try/except, assertion, or if statement. Conversely, if you expect IOErrors from the `read` and `close` calls, putting them within the `else` block will result in an unhandled exception. You could add another try/except block to check for IOErrors on these, but then I see no advantage of the `else` block compared to a null check on `f` after the initial `try/except` block. – topher217 Sep 27 '21 at 03:09
  • @topher217 "just check if f is not null" - or use an else statement, which is nicer, shorter and faster. "if you expect IOErrors" - Expectation is not relevant, it's if you want to handle them or not. In this case, a non-existent file is handled. Not being able to close an open file is not. This is normal. – Lennart Regebro Sep 27 '21 at 05:38
  • @LennartRegebro hmm. I'm not saying they shouldn't be used, I just think the arguments presented as to why they are "nicer" or "better" than a similar Java construct are a bit too much of a straw-man argument. I think `try/else`, assertions, `if/else` or other nullchecks have their place, but none of them being "nicer, shorter and faster" in all circumstances; specifically in the case that you wanted to handle both the IOErrors on `open` and from `read`/`close`, I think the nesting of `try/else` statements would end up getting quite convoluted. – topher217 Sep 27 '21 at 06:18
  • @topher217 If you are emotionally attached to Java, your opinion makes sense. But try/else is clearly both shorter and faster (since you save one if-test) that the alternative. "in all circumstances;" - Nobody said ALL circumstances. "specifically in the case that you wanted to handle both the IOErrors on open and from read/close" - Well, duh, obviously. Nobody said you aren't allowed to have more than one line of code in a try statement. The else is there for when you want to try statement to cover some code, and do something **else** if there is no exception. – Lennart Regebro Sep 27 '21 at 06:25
  • @LennartRegebro I wouldn't say I'm "not emotionally attached to Java" :P , but after using both in tandem for some time, its less about my love for Java and more about my hate for the seemingly "pythonic" preference for debugging based on runtime errors over compile errors that brought me here. – topher217 Sep 27 '21 at 06:32
  • @topher217 Called it. :-) – Lennart Regebro Sep 27 '21 at 07:32
3

From my understanding, the else clause is there to limit the scope of the try block to the code that you are trying to manage exceptions over. Alternatively your try blocks are larger and you may catch exceptions that you don't intend to catch.

Gleno
  • 16,621
  • 12
  • 64
  • 85
3

else is used for code that must be executed if the try clause does not raise an exception.

The use else is better than an additional try clause because else avoids accidentally catching an exception that wasn't raised by the code protected by the try except statement.

user225312
  • 126,773
  • 69
  • 172
  • 181
0

@John:
I think in languages like Java, or other ones, you have different exceptions. For example something like FileNotFound Exception (or something like this, I am not sure of the name).
This way you can handle different exceptions and act accordingly. Then you know why the error has occurred, because of open or close.