Python try-else
The statements in the else
block are executed if execution falls off the bottom of the try
- if there was no exception. Honestly, I've never found a need.
However, Handling Exceptions notes:
The use of the else clause is better than adding additional code to the try clause because it avoids accidentally catching an exception that wasn’t raised by the code being protected by the try ... except statement.
So, if you have a method that could, for example, throw an IOError
, and you want to catch exceptions it raises, but there's something else you want to do if the first operation succeeds, and you don't want to catch an IOError from that operation, you might write something like this:
try: operation_that_can_throw_ioerror()except IOError: handle_the_exception_somehow()else: # we don't want to catch the IOError if it's raised another_operation_that_can_throw_ioerror()finally: something_we_always_need_to_do()
If you just put another_operation_that_can_throw_ioerror()
after operation_that_can_throw_ioerror
, the except
would catch the second call's errors. And if you put it after the whole try
block, it'll always be run, and not until after the finally
. The else
lets you make sure
- the second operation's only run if there's no exception,
- it's run before the
finally
block, and - any
IOError
s it raises aren't caught here
There is one big reason to use else
- style and readability. It's generally a good idea to keep code that can cause exceptions near the code that deals with them. For example, compare these:
try: from EasyDialogs import AskPassword # 20 other lines getpass = AskPasswordexcept ImportError: getpass = default_getpass
and
try: from EasyDialogs import AskPasswordexcept ImportError: getpass = default_getpasselse: # 20 other lines getpass = AskPassword
The second one is good when the except
can't return early, or re-throw the exception. If possible, I would have written:
try: from EasyDialogs import AskPasswordexcept ImportError: getpass = default_getpass return False # or throw Exception('something more descriptive')# 20 other linesgetpass = AskPassword
Note: Answer copied from recently-posted duplicate here, hence all this "AskPassword" stuff.
Python try-else
What is the intended use of the optional
else
clause of the try statement?
The intended use is to have a context for more code to run if there were no exceptions where it was expected to be handled.
This context avoids accidentally handling errors you did not expect.
But it's important to understand the precise conditions that cause the else clause to run, because return
, continue
, and break
can interrupt the control flow to else
.
In Summary
The else
statement runs if there are no exceptions and if not interrupted by a return
, continue
, or break
statement.
The other answers miss that last part.
The optional
else
clause is executed if and when control flows off the end of thetry
clause.*
(Bolding added.) And the footnote reads:
*Currently, control “flows off the end” except in the case of an exception or the execution of a
return
,continue
, orbreak
statement.
It does require at least one preceding except clause (see the grammar). So it really isn't "try-else," it's "try-except-else(-finally)," with the else
(and finally
) being optional.
The Python Tutorial elaborates on the intended usage:
The try ... except statement has an optional else clause, which, when present, must follow all except clauses. It is useful for code that must be executed if the try clause does not raise an exception. For example:
for arg in sys.argv[1:]: try: f = open(arg, 'r') except IOError: print 'cannot open', arg else: print arg, 'has', len(f.readlines()), 'lines' f.close()
The use of the else clause is better than adding additional code to the try clause because it avoids accidentally catching an exception that wasn’t raised by the code being protected by the try ... except statement.
Example differentiating else
versus code following the try
block
If you handle an error, the else
block will not run. For example:
def handle_error(): try: raise RuntimeError('oops!') except RuntimeError as error: print('handled a RuntimeError, no big deal.') else: print('if this prints, we had no error!') # won't print! print('And now we have left the try block!') # will print!
And now,
>>> handle_error()handled a RuntimeError, no big deal.And now we have left the try block!