Python中如何调用受保护方法?

1 投票
4 回答
1480 浏览
提问于 2025-04-16 14:50

我有一系列的调用,这些调用都有可能出现错误,我想找到一个好的方法来保护这些调用。我正在尝试在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

有没有更好的方法来做到这一点呢?也许可以用注解?

为了澄清一下,我想在原始方法上加注解,也就是说:

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

这就是我想要的:

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

4 个回答

1

听起来像是需要用到装饰器的工作

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

装饰器非常适合这个情况:

def protected_call(method):
    def wrapper(*args, **kwargs):
        try:
            return method(*args, **kwargs)
        except:
            pass
    return wrapper

示例用法:

@protected_call
def foo():
    raise Exception()

# nothing is being raised
foo()
3

正如nmichaels所建议的,这种情况最好通过with语句来处理。

@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

撰写回答