473,385 Members | 1,445 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,385 software developers and data experts.

Best way to handle exceptions with try/finally

Hey python people,

I'm interested in using the try/finally clause to ensure graceful
cleanup regardless of how a block of code exits. However, I still am
interested in capturing the exception.

The scenario is that I have an object that accesses a global memory
space accessible via multiple threads. When shared resources are
accessed a lock is acquired and then released. In the case that someone
tries to access a variable that doesn't exist, I still need to release
the lock so that other threads can continue their work, but an exception
should be raised to the caller.

Anyhow, I was playing with ideas in my code, and in this attempt I
attempted to nest "try"s to at least make sure that accessing variables
was raising an exception. That's the case, and then I attempt to raise
the exception "ValueError" so that the calling function will get the
exception. This doesn't work though. It seems that any exceptions get
caught up in that "try/finally" and i can't get the exception to raise
higher than that without raising it outside of this try. Is the best
thing to do to have the exception mechanism set some type of flag that I
can check during the "finally" statement?

##CODE##

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

def putVar(self, variableName, value):
self.__mutex.acquire() #accessing shared dictionary
try:
self.__userData[variableName] = value
finally:
self.__mutex.release()
return

--

Carl J. Van Arsdall
cv*********@mvista.com
Build and Release
MontaVista Software

May 23 '06 #1
12 1721
I guess the following standard method will help :

class MyLocker(object):
def __init__(self, lock):
self.lock = lock
self.lock.acquire()

def __del__(self):
self.lock.release()

Then whenever you need to acquire a lock:
templock = MyLocker(self.__mutex)

del templock # will release the lock (provided you didn't create an
extra link to this object)

May 24 '06 #2
Unindent your first return statement. The return statement in putVar is
not needed.

May 24 '06 #3
"Carl J. Van Arsdall" <cv*********@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()
May 24 '06 #4
Am Tue, 23 May 2006 12:47:05 -0700 schrieb Carl J. Van Arsdall:
Hey python people,

I'm interested in using the try/finally clause to ensure graceful
cleanup regardless of how a block of code exits. However, I still am
interested in capturing the exception.


You can reraise the exception:

try:
something()
except:
cleanup()
raise # reraise the caught exception

--
Thomas Güttler, http://www.thomas-guettler.de/
E-Mail: guettli (*) thomas-guettler + de
Spam Catcher: ni**************@thomas-guettler.de

May 24 '06 #5
In article <11*********************@38g2000cwa.googlegroups.c om>,
"Maxim Sloyko" <m.******@gmail.com> wrote:
I guess the following standard method will help :

class MyLocker(object):
def __init__(self, lock):
self.lock = lock
self.lock.acquire()

def __del__(self):
self.lock.release()

Then whenever you need to acquire a lock:
templock = MyLocker(self.__mutex)

del templock # will release the lock (provided you didn't create an
extra link to this object)


Warning! Danger, Will Robinson! Evil space aliens are trying to write C++
in Python! Quick, we must get back to the ship before they eat our brains!

The problem here is that there is no guarantee that __del__() will get
called at any predictable time (if at all). C++ uses deterministic object
destruction. Python doesn't destroy (finalize?) objects until the garbage
collector runs.

See PEP-343 (http://www.python.org/dev/peps/pep-0343/) for the new "with"
statement which should solve problems like this. If I understand things
right, "with" will be included in Python-2.5, which is due out Real Soon
Now.
May 24 '06 #6
Carl J. Van Arsdall wrote:
(snip)

Not an answer to your question, just a few comments on your code:
class Shared:
class Shared(object):

def __init__(self):
self.__userData= {}
self.__mutex = threading.Lock() #lock object
Don't use __names unless you have a *really* strong reason to do so.
'protected' attributes are usually noted as _name.
def getVar(self, variableName):
temp = None
error = 0
self.__mutex.acquire() #accessing shared dictionary
try:
try:
temp = self.__userData[variableName]
except:
Don't use bare except clauses. Specify the exceptions you intend to
handle, let the other propagate.

I once spent many hours trying to debug a badly written module that has
such a catch-all clause with a misleading error message saying some file
could not be opened when the actual problem was with a wrong login/pass
for a connection.
print "Variable doesn't exist in shared
space"
stdout is for normal program outputs. Error messages should go to stderr.
raise ValueError
Should be a LookupError subclass. And the message should go with the
exception:
raise MyLookupErrorSubclass("Variable '%s' doesn't exist in shared
space" % variableName)

finally:
self.__mutex.release()
return temp

def putVar(self, variableName, value):
self.__mutex.acquire() #accessing shared dictionary
try:
self.__userData[variableName] = value
finally:
self.__mutex.release()
return


The return statement is useless here.

My 2 cents.
--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in 'o****@xiludom.gro'.split('@')])"
May 24 '06 #7
Doing cleaup in except is not the Python way. This is what finally is
for. Using except you would have to at least say:

try:
stuff()
cleanup()
except:
cleanup()
raise

Duplicate code - not nice. finally is the Python way:

try:
stuff()
finally:
cleanup()

That's it. But the return statement should not be a part of finally if
you want exceptions to propagate out of the function containing
try/finally. As mentioned multiple times in the thread.

May 24 '06 #8
Zameer wrote:
That's it. But the return statement should not be a part of finally if
you want exceptions to propagate out of the function containing
try/finally. As mentioned multiple times in the thread.

Ah, great, that was it. Thanks to everyone for their help, I got a lot
of really useful information from your replies. I tend to put "return"
statements at the end of functions to make an attempt at being clean. I
realize that a lot of the time functions will just return but I was
hoping by explicitly stating my function returns that another person
reading my code would more easily see any exit points in my code. Turns
out that it came to bite me later.

Again, thanks to all your help and comments on my coding style.

..c

--

Carl J. Van Arsdall
cv*********@mvista.com
Build and Release
MontaVista Software

May 24 '06 #9
> I tend to put "return"
statements at the end of functions to make an attempt at being clean. I
realize that a lot of the time functions will just return but I was
hoping by explicitly stating my function returns that another person
reading my code would more easily see any exit points in my code. Turns
out that it came to bite me later.


You can put the return statement at the end.

try:
stuff()
finally:
cleanup()
return

The return statement is not necessary in this case, but it's not in the
finally part either. If you like it, keep it. Just don't make it part
of finally if you want exceptions to propagate.

I can see where you are going by making the return statement part of
finally, and I actually expected it to work the same as if it was not
part of finally. Turns out it doesn't. Can somebody please comment on
how this works in other languages? I know that finally is not a part of
standard C++ but Borland and Microsoft compilers allow use of the
keyword __finally. Delphi also has finally and I seem to recall that
returning from the finally part does not prevent the exception from
propagating, but memory may not serve me right.

Thank you for "raising" this quite interesting question.

May 24 '06 #10
We used to have a try..except..finally syntax in Python. It was taken
out a while ago for reasons unknown to me. The good news is that it is
back in Python 2.5.

I haven't tested it, but Guido said so himself:
http://video.google.com/videoplay?do...31183357868340

May 24 '06 #11
I wonder where the "else" goes in try..except..finally...

May 25 '06 #12
Zameer wrote:
I wonder where the "else" goes in try..except..finally...

try / except / else / finally

See the PEP:
http://www.python.org/dev/peps/pep-0341/

Kent
May 25 '06 #13

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: Mark Hoffman | last post by:
All, My application spawns a worker process by calling BeginInvoke with an asynchronous callback method. This callback method is responsible for calling EndInvoke. No problems there; pretty much...
5
by: | last post by:
Unfortunately I've used exception handling as a debugging tool. Now I want to be smarter about handling errors. Today in the global.asx in the Application_OnError event, I inserted code to email...
1
by: Ricardo | last post by:
Ok, the new .net 2.0 allows us to bind a server control to a data source without writing a line of code. Now, what happens if there is a problem accessing the data source and an exception is...
4
by: Boni | last post by:
Dear all, is it possible to handle 2 exception tipes in one block? I.e Try if XXX then
3
by: chris | last post by:
hello, I can't seem to make this work: VS2005 I have a simple program that uses a backgroundworker control to execute a long process (webservice call) if that webservice call fails, i want to...
10
by: tcomer | last post by:
Hello! I've run into a problem and I can't seem to understand "why" the problem occurs. In my program: using System; using System.IO; using System.Xml; namespace MyNamespace { class MainApp
1
by: beginner | last post by:
Hi All, I am wondering if there is any way to handle exceptions inside list comprehension. For example, I want to skip the point if f(x) raises an exception. How can I do that without...
0
by: iowna uass | last post by:
Hi, I'm converting a dll from VB6 to VS2008 and I have a question on when exception handling should be used. The dll is a custom module that integrates security into our corporate applications...
6
by: Author | last post by:
I am writing a small library in C#, which will be compiled to dll and shared by multiple applications. This is sorta new to me. I am wondering how professionals handle exceptions in a dll...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.