On May 12, 2:35 am, Steven D'Aprano <ste...@remove.this.cybersource.com.au> wrote: > On Tue, 12 May 2009 09:20:36 +0000, Steven D'Aprano wrote: > > On Tue, 12 May 2009 20:23:25 +1200, Lawrence D'Oliveiro wrote: > > >> In message <gu7f97$mt...@reader1.panix.com>, kj wrote: > > >>> I know about the construct: > > >>> try: > >>> # do something > >>> except ...: > >>> # handle exception > >>> else: > >>> # do something else > > >>> ...but I can't come with an example in which the same couldn't be > >>> accomplished with [no else] > > >> I'd agree. If you have to resort to a "try .. else", then might I > >> respectfully suggest that you're using exceptions in a way that's > >> complicated enough to get you into trouble. > > > try: > > rsrc = get(resource) > > except ResourceError: > > log('no more resources available') > > raise > > else: > > do_something_with(rsrc) > > finally: > > rsrc.close() > > Except of course such a pattern won't work, because if get(resource) > fails, rsrc will not exist to be closed. So a better, and simpler, > example would be to drop the finally clause:
Resource acquisition goes outside the try block. If you want to log an error, then get() goes inside its own try block. try: rsrc = get(resource) except ResourceError: log('no more resources available') raise try: do_something_with(rsrc) finally: rsrc.close() If you hadn't reraised the exception, then the else clause would have been useful as follows: try: rsrc = get(resource) except ResourceError: proceed_without_resource() else: try: proceed_with_resource() # Note: proceed_with_resource() can possibly raise # ResourceError itself finally: rsrc.close() The main reason for the else clause on try blocks is so that you don't risk catching spurrious exceptions. You could stick proceed_with_resource() in the try clause, but then if proceed_with_resource() throws ResourceError because it tries to acquire a different resource and fails, then it'd be caught and proceed_without_resource() would be called, which is a mistake. In general, you want to limit the contents of a try clause to code that throws an exception you want to catch (if you're trying to catch an exception); everything else should go into the else clause. Incidentally, I can't think of any realistic use cases for using all four of try...except...else...finally. Carl Banks -- http://mail.python.org/mailman/listinfo/python-list