Reputation: 2052
In a Python program I have code with the following structure:
try:
value = my_function(*args)
finally:
with some_context_manager:
do_something()
if 'value' in locals():
do_something_else(value)
But the 'value' in locals()
construction feels a bit fragile and I am wondering if there is a better way to do this.
What I really want is for the code inside the finally
to behave slightly different depending on whether the try
block raised an exception. Is there a way to know if an exception was raised?
Upvotes: 5
Views: 2335
Reputation: 23763
Assign the exception to a variable in the except suite then use it in the finally suite.
foo = False
try:
raise KeyError('foo not found')
except KeyError as e:
pprint(e)
foo = e
finally:
if foo:
print(foo)
else:
print('NO')
Upvotes: -1
Reputation: 640
Here are a couple ideas:
Set value before attempting the try:
value = None
try:
value = my_function(*args)
finally:
with some_context_manager:
do_something()
if value is not None:
do_something_else(value)
Or if you want to set the value based on the exception type:
try:
value = my_function(*args)
except:
value = None
raise
finally:
with some_context_manager:
do_something()
if value is not None:
do_something_else(value)
Upvotes: 1
Reputation: 811
If the goal is "when an exception was raised, do something different", how about:
exception_raised = False
try:
value = my_function(*args)
except:
exception_raised = True
raise
finally:
with some_context_manager:
do_something()
if not exception_raised:
do_something_else(value)
Now, if you're going to have multiple exceptions that you actually do something with, I'd recommend:
completed_successfully = False
try:
value = my_function(*args)
else:
completed_successfully = True
finally:
with some_context_manager:
do_something()
if completed_sucessfully:
do_something_else(value)
Upvotes: 3