469,328 Members | 1,327 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,328 developers. It's quick & easy.

Simple exceptions question

Say I have a function foo that throws an IndexError exception, and I
want to handle it:

def foo(a, b, c):
print a[10], b[10], c[10] #, etc.

def main():
#define vars
try:
foo(a, b, c)
except IndexError:
print "Accessed array ", x, " out of bounds!" #???

When the exception is thrown, I don't know what triggered it! a, b,
or c?

I could put a series of if statements in the except clause, but that
defeats the whole purpose of having the exception, right? Is there a
better way?

Thanks in advance!

--Nick
Jul 18 '05 #1
5 1421
Nick Jacobson wrote:
Say I have a function foo that throws an IndexError exception, and
I want to handle it:

def foo(a, b, c):
print a[10], b[10], c[10] #, etc.

def main():
#define vars
try:
foo(a, b, c)
except IndexError:
print "Accessed array ", x, " out of bounds!" #???

When the exception is thrown, I don't know what triggered it! a,
b, or c?
There is IMHO no (at least no obvious) way to find it out. The
"print" is a single statement - an atom from the point of view of
the python interpreter. Its easy to find out, which statement caused
the exception. But its impossible to find out which "part" of one
single statement caused an exception.

And btw what value should "x" have? An object in python has no name.
I could put a series of if statements in the except clause, but
that
defeats the whole purpose of having the exception, right? Is there
a better way?


Yes: create your own list class (maybe by inheriting list). Give each
instance an unique name. Use a setitem method like this:

class seq(list):
# some code suppressed...
def __getitem__(self,index):
try: list.__getitem__(self,index)
except IndexError,e:
e.index = index
e.name = self.name
raise e

Thus you can write the except clause as:

except IndexError, e:
print "Accessed*array*", e.name, "*out*of*bounds at", e.index

Mathias
Jul 18 '05 #2
Nick Jacobson wrote:
Say I have a function foo that throws an IndexError exception, and I
want to handle it:

def foo(a, b, c):
print a[10], b[10], c[10] #, etc.

def main():
#define vars
try:
foo(a, b, c)
except IndexError:
print "Accessed array ", x, " out of bounds!" #???

When the exception is thrown, I don't know what triggered it! a, b,
or c?

I could put a series of if statements in the except clause, but that
defeats the whole purpose of having the exception, right? Is there a
Not necessarily. If you expect the IndexError to be rare you could easily
afford the extra time to detect the source of the error.
better way?


The problems I see with your approach:

You are interested in the details of a failure that happens in another
function. That breaks the abstraction and I'd rather invent a custom
Exception.

You wrap multiple points of failure into one try block when you are
interested in the exact source of failure.

foo() can "semi-fail", i. e. start printing something and then choke.

Here is how I would do it:

class FooError(Exception): pass

def foo(a, b, c):
try:
a = a[10]
except IndexError:
raise FooError("a out of bounds")

try:
b = b[10]
except IndexError:
raise FooError("b out of bounds")

try:
c = c[10]
except IndexError:
raise FooError("c out of bounds")

print a, b, c
def main():
try:
foo(*map(range, [11, 11, 5]))
except FooError, e:
print "Problem in foo():", e

main()
Peter

Jul 18 '05 #3
Thanks for the reply! I'm definitely trying this out..
the python interpreter. Its easy to find out, which statement caused
the exception.
How can you do that?
Yes: create your own list class (maybe by inheriting list). Give each
instance an unique name. Use a setitem method like this:

class seq(list):
# some code suppressed...
def getitem (self,index):
try: list. getitem (self,index)
except IndexError,e:
e.index = index
e.name = self.name
raise e

Thus you can write the except clause as:

except IndexError, e:
print "Accessed array ", e.name, " out of bounds at", e.index

Mathias


It says that "self.name" is undefined:
"AttributeError: 'seq' object has no attribute 'name'"
Jul 18 '05 #4
Not sure if this is all you need, but have tried this?

def main():
#define vars
try:
foo(a, b, c)
except IndexError:
traceback.print_exc()
Jul 18 '05 #5
Not sure if this is all you need, but have tried this?

def main():
#define vars
try:
foo(a, b, c)
except IndexError:
import traceback
traceback.print_exc()
Jul 18 '05 #6

This discussion thread is closed

Replies have been disabled for this discussion.

By using this site, you agree to our Privacy Policy and Terms of Use.