Best way to handle exceptions with try/finally

Roy Smith roy at panix.com
Wed May 24 13:59:05 CEST 2006


"Carl J. Van Arsdall" <cvanarsdall at mvista.com> wrote:

> class Shared:
>         def __init__(self):
>                 self.__userData= {}
>                 self.__mutex = threading.Lock() #lock object
> 
>         def getVar(self, variableName):
>                 temp = None
>                 error = 0
>                 self.__mutex.acquire() #accessing shared dictionary
>                 try:
>                         try:
>                                 temp = self.__userData[variableName]
>                         except:
>                                 print "Variable doesn't exist in shared space"
>                                 raise ValueError
>                 finally:
>                         self.__mutex.release()
>                         return temp

A few comments on this.

First, it's almost always a bad idea to have a bare "except:", because that 
catches *every* possible exception.  You want to catch as specific an 
exception as you can (in this case, I suspect that's KeyError).

Second, I'm not sure if your intent was to return from the function or to 
raise an exception on an unknown variableName.  You can't do both!  Quoting 
from http://docs.python.org/ref/try.html..

> When an exception occurs in the try clause, the exception is temporarily 
> saved, the finally clause is executed, and then the saved exception is 
> re-raised. If the finally clause raises another exception or executes a 
> return or break statement, the saved exception is lost.

so with the code you posted (from sight; I haven't tried running it), what 
will happen is:

1) __userData[variableName] raises KeyError

2) The KeyError is caught by the inner try block and the except block runs, 
which in turn raises ValueError

3) The ValueError is caught by the outer try block and the finally block 
runs, releasing the mutex, discarding the ValueError exception, and 
returning temp

4) Whoever called getVar() will see a normal return, with a return value of 
None (because that's what temp was set to in the first line of getVar()



More information about the Python-list mailing list