信号警报不会引发错误

时间:2017-12-28 18:06:26

标签: python python-2.7 signals

在下面的代码中,我试图创建一个类'TimedExecutor',如果超过一定的时间限制,它将停止执行传递给其方法'execute'的函数(bar)。但是,即使显示错误消息,程序执行也不会停止。

注意:我们不得对函数bar()进行任何更改,因为它是由外部模块提供的。

import signal
import time

class MyError(Exception):
  """Base error"""

class MyInheritedError(MyError):
  """Class to inherit from base error"""


class TimeoutListener(object):
  def __init__(self, timeout_seconds, error_message="Timeout executing."):
    self.timeout_seconds = timeout_seconds
    self.error_message = error_message
    self.alarm = None

  def __enter__(self):
    signal.signal(signal.SIGALRM, self._handle_timeout)
    signal.alarm(self.timeout_seconds)

  def __exit__(self, listener_type, value, traceback):
    # Disable the alarm.
    if self.alarm:
      self.alarm = None
    else:
      signal.alarm(0)

  def _handle_timeout(self, signum, frame):
    print("Got the signum %s with frame: %s" % (signum, frame))
    raise MyInheritedError(self.error_message + "aditya")


class TimedExecutor(object):
  @staticmethod
  def execute(timeout_secs, functor, *args, **kwargs):
    msg = "Timeout executing method - %s." % functor.__name__
    timeout_signal = TimeoutListener(timeout_secs, error_message=msg)
    try:
      with timeout_signal:
        output = functor(*args, **kwargs)
    except MyInheritedError as ex:
      print("%s did not complete in %s: %s."
            % (functor.__name__, timeout_secs, repr(ex)))
      raise
    return output


def bar():
  for _ in range(5):
    try:
      time.sleep(1)
      print("SLEEPING")
    except MyInheritedError as ex:
      print ex


ob = TimedExecutor.execute(2, bar)

1 个答案:

答案 0 :(得分:0)

你的算人吞下了你想要致命的异常。

bar()除了子句之外,其中一个循环打印然后丢弃TimeoutListener上下文管理器引发的错误。然后循环重新开始。

bar()可能不应该知道您TimedExecutor可能引发的异常。相反,bar()调用.execute()的调用方应该知道它:

from aditya.utils import TimedExecutor, TimeoutException

...

try:
  TimedExecutor.execute(2, bar)
except TimeoutException:
  print("Timed out executing bar")