try:
#code to do something
if (condition):
raise ValueError
except java.lang.NullPointerException, ValueError:
#code to print exception message
continue
UnboundLocalError: local: 'ValueError'
This is when I learnt about one of the inner workings of python.
The python interpretor scans the code block once. if a name is bound to a variable with out being specified as global, it is considered local.
e.g:
x = 2
def func():
x = 3
print x
func()
print x
will print
3
2
This is because in func, x is bound locally to the variable containing the value <3>.
But the same function with the small difference will fail with 'UnBoundLocalError: local: x':
x = 2
def func():
print x
x = 3
func()
print x
This is again because, the interpreter first scans func. It sees x is bound locally as it is assigned a value 3 within the innerscope. When it tries to execute, the print statement precedes the binding statement. At the point, x is a free variable with no binding. Hence the error.
Now in the case of the exception handling,
The construct is
try:
#Do something
except Exception, e:
#e is bound to exception obj.
#Do something with e
e is actually bound to the instance of the class Exception and becomes a local variable.
Now considering the initial scenario, the ValueError name is bound to the instance of the 'java.lang.NullPointerException' exception. This overrides the scope of the global builtins and makes ValueError a binding to local variable and the binding happens at the except line. So when raise ValueError is called an UnboundLocalError is thrown.
So how to we handle multiple exceptions?
try:
#code to do something
if (condition):
raise ValueError
except (java.lang.NullPointerException, ValueError):
#code to print exception message
continue
For more interesting patterns see here.