Simple exceptions question

N

Nick Jacobson

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
 
M

Mathias Waack

Nick said:
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
 
P

Peter Otten

Nick said:
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
 
N

Nick Jacobson

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'"
 
R

R.Marquez

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()
 
R

R.Marquez

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()
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,202
Messages
2,571,057
Members
47,667
Latest member
DaniloB294

Latest Threads

Top