【问题标题】:The proper Python exception to break out of an infinite loop (that shouldnt be infinite)打破无限循环的正确 Python 异常(不应该是无限的)
【发布时间】:2014-07-19 13:10:07
【问题描述】:

这是我的简化代码:

x = 0
while True:
    x += 1
    if not do_stuff(x)
        break
    if x > 1000000:
        raise Exception("Too many iterations")

1000000 是 x 的值,永远不应达到。如果是,则出现问题并引发异常。对于这样的用例,Exception 的正确子类是什么(如果存在的话)?

【问题讨论】:

  • 出了什么问题?输入,还是程序逻辑?换句话说:是最终用户的错误,还是程序员的错误?
  • Out 听起来像是提升 AssertionError 或从 RuntimeException 继承并提升它的案例。
  • 就我而言,do_stuff 正在打开一个网页,但我想知道是否存在失控循环的一般例外情况。 (所以是程序员的错误)
  • 没有内置异常。只需从 Exception 派生一个即可。
  • 我最后写的只是assert x < 1000000

标签: python loops exception


【解决方案1】:

不会发生这种情况的唯一方法是 do_stuff 永远不会返回 false。

如果是这种情况,请创建自定义异常。 我通常会创建一个 MiscException(以及更具体的异常)

【讨论】:

  • 创建和捕获自定义异常的好处是您不会意外捕获其他更重要的异常。
  • 这个答案没有回答这个问题,“对于这样的用例,什么是 Exception 的正确子类”。答案要么是内置的异常类型,要么是没有这样的异常类型。请更新答案以明确说明此信息。
  • @Rafe 为什么答案必须是内置类型,或者没有这种类型?我认为定义一个自定义类对于快速诊断来说太过分了,但这似乎是对狭隘问题的有效答案。
  • @Rafe,啊,也许你不明白“创建自定义异常”涉及从 Exception 派生类?也就是说,创建一个新的 Exception 子类。
【解决方案2】:

如果你不想,你根本不需要使用异常:

for i in xrange(1000000):
    if not do_stuff(x):
        break
else:
    # too many iterations, do something else.

for/else 结构有点奇特,但正好适合这个用例。如果循环从未中断,则执行 else 子句。这里有更多解释:http://nedbatchelder.com/blog/201110/forelse.html

如果您想使用异常进行快速诊断,请不要过度考虑要使用的类。例外很好。如果您担心某些东西可能会捕获您的异常,请使用 ZeroDivisionError,这很容易引发:

if x > 1000000:
    1/0

【讨论】:

  • 感谢您指出这一点,但重点是提出一个例外以进行快速诊断。
  • @ToonAlfrink 好的,您可以从 else 子句引发异常。它仍然是一种比带有递增变量的 while 循环更紧凑的形式。
  • 投反对票。这应该是评论,而不是答案。这个问题是有效的。请不要评论用于说明问题的代码模式。问题是,“对于这样的用例,什么是 Exception 的正确子类”。
  • @Rafe,我已添加到我的答案中。
【解决方案3】:

我也有同样的问题。我无法为此找到python内置的任何东西。 IPython 使用RuntimeError('maximum recursion depth exceeded')

【讨论】:

  • RuntimeError 是一个内置异常
  • RuntimeError 是一个广泛的例外。问题的隐含意义是询问特定的例外情况。
猜你喜欢
  • 2012-04-02
  • 1970-01-01
  • 2013-03-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多