Protected method call in Python?
I have a sequence of calls that I need to make, all of which could throw an exc开发者_如何学运维eption and I want a good way of protecting the calls. I am trying to find a more professional way to do the following in python:
def protected_call(method):
result = None
try:
result= method()
except: pass
return result
class Test():
def terminate():
protected_call(self.could_throw_exception)
protected_call(self.receiver.stop)
protected_call(self.connection.stop)
#etc
Is there a better way to do this ? Maybe with an annotation ?
Just to clarify, I dont want to put an annotation on the original method ie:
class Receiver():
@protected
def stop():
print 'I dont want to do this'
class Test():
@protected
def could_throw_exception():
print 'dont want this'
def stop():
self.could_throw_exception()
self.receiver.stop()
This is what i want:
class Receiver():
def stop():
print 'I want this'
class Test():
def could_throw_exception():
print 'like this'
'''This one cares about crashing'''
def stop()
self.could_throw_exception()
self.receiver.stop()
self.connection.stop()
'''This one does not'''
def terminate():
#i want to define it at the call level.
@protected
self.could_throw_exception()
@protected
self.receiver.stop()
As nmichaels suggested, this kind of thing is best handled via the with
statement.
@contextlib.contextmanager
def suppress_exceptions(*exceptions):
if not exceptions:
exceptions = Exception
try:
yield
except exceptions:
# You would log an error here
# If you have logging in your application
pass
with suppress_exceptions():
1/0
print("Ignored the exception!")
with suppress_exceptions(IOError):
1/0
# The second one will let the exception through
Decorator would be perfect for this:
def protected_call(method):
def wrapper(*args, **kwargs):
try:
return method(*args, **kwargs)
except:
pass
return wrapper
Sample usage:
@protected_call
def foo():
raise Exception()
# nothing is being raised
foo()
Sounds like a job for a decorator
def protected_call(func):
def inner(*args, **kw):
try:
return func(*args, **kw)
except:
pass
return inner
class Test():
@protected_call
def throws_exception(self):
print 1/0
@protected_call
def no_exception(self):
print 4
def sometimes_need_exception(self):
print 5
protected_sometimes_need_exception = protected_call(sometimes_need_exception)
def stop(self):
self.throws_exception()
self.no_exception()
At least logging exceptions seems to be a useful feature here or how else will you have control over unexpected errors...?
精彩评论