【问题标题】:How to write an infinite loop that an exception can't break?如何编写一个异常不能中断的无限循环?
【发布时间】:2015-01-18 22:39:28
【问题描述】:

是否可以编写一个无限循环,即使在循环体的执行之间发生异常,异常也无法中断?如果是这样,怎么做? (当我思考稳健性时,我会想到这些愚蠢的事情。)

例如,考虑以下代码:

import time

def slow_true():
    print 'waiting to return True...'
    time.sleep(1.0)
    return True

while slow_true():
    try:
        print 'in loop body'
        raise RuntimeError('testing')
    except:
        print 'caught exception, continuing...'
        continue

当 Python 正在执行 slow_true() 时,我可以使用 Ctrl-C 轻松跳出循环。即使我将while slow_true(): 替换为while True:,理论上也有一小段时间(在执行主体之间)SIGINT 可以导致脚本退出。

我意识到我可以实现一个 SIGINT 处理程序来有效地禁用 Ctrl-C,但这不是这个问题的重点。

我可以用另一个无限循环来包装循环并将try/except 移出一个级别,如下所示:

import time

def slow_true():
    print 'waiting to return True...'
    time.sleep(1.0)
    return True

while True:
    try:
        while slow_true():
            print 'in loop body'
            raise RuntimeError('testing')
    except:
        print 'caught exception, restarting...'
        continue
    break

这将使跳出循环变得更加困难(必须在正确的时间背靠背引发两个异常),但我认为这在理论上仍然是可能的。

【问题讨论】:

  • 您有什么问题吗?您似乎只是想陈述事实或接受意见而不是答案。
  • @PythonMaster:我没有问题——我有一个问题。这个问题在一开始就说明了:“是否有可能编写一个无限循环,即使在循环体的执行之间发生异常也无法打破异常?”
  • 嗯,你真的应该避免是/否问题。
  • @PythonMaster:有一个暗示“如果是这样,怎么做?”那里的问题。我将编辑我的问题以明确暗示的问题。
  • @PythonMaster 是/否问题仍然需要证明。如果可能,则需要代码示例或文档证明。如果不是,则需要一些相反的来源。

标签: python python-2.7 loops exception-handling infinite-loop


【解决方案1】:

一个绝对不推荐的选项是覆盖异常钩子方法。

import sys

def exception_hook(exception_type, value, traceback):
    your_loop_function()

sys.excepthook = exception_hook

使用信号的替代解决方案(不太糟糕):

import signal

def interrupt(signal, frame):
    your_loop_function()

signal.signal(signal.SIGINT, interrupt)

【讨论】:

  • 所以这会阻止抛出异常?还是异常会触发这个函数(exception_hook)?
  • 异常会触发函数,让你可以继续。或者,正如您所指出的那样,您将永远堆叠 try/except 块。
  • 聪明。如果your_loop_function() 本身引发异常会怎样?
  • @RichardHansen:一个无限循环,将触发最大递归深度错误,这……这肯定会杀死你的解释器。这就是为什么我绝对不推荐它;)
  • 该替代解决方案如何防止异常中断循环?处理信号时是否禁用异常?如果有一个引发异常的SIGUSR1 处理程序怎么办?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-13
  • 1970-01-01
  • 2019-08-07
  • 1970-01-01
  • 1970-01-01
  • 2013-03-19
相关资源
最近更新 更多