Repetitive Try And Except Clauses
Solution 1:
Python Decorators are what you want.
You said the except block is always the same. Make a custom decorator that does what you want. You'll have to apply this to each function/method but it sure does save duplication.
def handleError(function):
def handleProblems():
try:
function()
except Exception:
print "Oh noes"
return handleProblems
@handleError
def example():
raise Exception("Boom!")
When calling a method with the decorator applied:
>>> >>> example() Oh noes >>>
You will need to change the exception types as well as what you do, but you get the jist of where I'm going with this.
Solution 2:
The answer above does not apply for Functions that take arguments - for the later case, I think you would want something like this:
def handleError(f):
def handleProblems(*args, **kwargs):
try:
return f(*args, **kwargs)
except Exception:
print "Oh noes"
return handleProblems
We can test it like so:
@handleError
def addTwo(x, y):
print(x + y)
>>> addTwo(5,5)
10
>>> addTwo(5, 's')
Oh noes
Solution 3:
The content inside your try
block is the interesting stuff, so that should be in functions. Then just select which function you want, and call it, wrapped by your exceptions. You could even write the exception code as a function, and pass the selected function to this as an argument. e.g.
def foo():
num=random.random()
if num>0.5: print 'OK'
elif num>0.25: raise NameError('Too Small')
else: raise KeyboardInterrupt
def bar():
num=random.random()
if num>0.8: print 'OK'
elif num>0.6: raise NameError('Too Small')
else: raise KeyboardInterrupt
def try_numerics(f):
try:
f()
except NameError:
print "%s had a NameError" % sys._getframe().f_code.co_name
except:
print "%s had a different Error" % sys._getframe().f_code.co_name
# In your main code...
if (need_to_run_foo):
try_numerics(foo)
elif (need_to_run_bar):
try_numerics(bar)
Solution 4:
If those are your actual functions it would be easy to generalize them.
You could create one general function
def general(bottom_num, top_num):
num=random.random()
try:
if num>top_num: print 'OK'
elif num>bottom_num: raise NameError('Too Small')
else: raise KeyboardInterrupt
except NameError:
print "%s had a NameError" % sys._getframe().f_code.co_name
except:
print "%s had a different Error" % sys._getframe().f_code.co_name
this would keep your code from repeating and address the try: except: issue
Solution 5:
I ran into the same scenario recently, in my case I have some custom exceptions based on which I need to log or raise the Exception further. I have created a decorator method to handle the exceptions as per type.
try:
obj.some_method()
except Exception as e:
catch_and_log_exception(e)
def catch_and_log_exception(e):
if isinstance(e, MyConnectionError):
print "Connection error : %s." % e.message
sys.exit(1)
elif isinstance(e, MyConnectionTimeout):
print "Connection to server has been timed out. %s" % e.message
sys.exit(1)
elif isinstance(e, MyException):
message = e.explanation if e.explanation else e.message
log_error_message(str(message))
print "Failed, please check the logs."
sys.exit(1)
else:
raise e
Hope this help !!
Post a Comment for "Repetitive Try And Except Clauses"