6

为什么/如何创建一个看似无限的循环?错误地,我认为这会导致某种形式的堆栈溢出类型错误。

i = 0

def foo () :
    global i

    i += 1
    try :
        foo()
    except RuntimeError :
        # This call recursively goes off toward infinity, apparently.
        foo()

foo()

print i
4

2 回答 2

6

RuntimeError如果超出递归限制,将引发异常。

由于您正在捕获此异常,因此您的机器将继续运行,但您只是添加到单个全局 int 值,它不会使用太多内存。

您可以使用 设置递归限制sys.setrecursionlimit()。电流限制可以通过 找到sys.getrecursionlimit()

>>> import sys
>>> sys.setrecursionlimit(100)
>>>
>>> def foo(i):
...     i += 1
...     foo(i)
...
>>> foo(1)
Traceback (most recent call last):
  ...
  File "<stdin>", line 3, in foo
RuntimeError: maximum recursion depth exceeded
>>>

如果您想用完内存,请尝试消耗更多内存。

>>> def foo(l):
...     l = l * 100
...     foo(l)
...
>>> foo(["hello"])
Traceback (most recent call last):
  ...
  File "<stdin>", line 2, in foo
MemoryError
>>>
于 2012-06-27T09:09:42.290 回答
4

如果您将代码更改为

i = 0
def foo ():
    global i
    i += 1
    print i
    try :
        foo()
    except RuntimeError :
        # This call recursively goes off toward infinity, apparently.
        foo()
    finally:
        i -= 1
        print i

foo()

您将观察到输出在 999 以下振荡(1000 是 Python 的默认递归限制)。RuntimeError这意味着foo(),当达到限制时(

如果您提出 a KeyboardInterrupt,您将观察到整个跟踪是如何立即终止的。


更新

有趣的是,第二个调用foo()不再受try ... except-block 保护。因此,应用程序实际上最终会终止。如果您将递归限制设置为较小的数字,这将变得很明显,例如sys.setrecursionlimit(3)

$ python test.py
1
2
1
2
1
0
Traceback (most recent call last):
  File "test.py", line 19, in <module>
    foo()
  File "test.py", line 14, in foo
    foo()
  File "test.py", line 14, in foo
    foo()
RuntimeError
于 2012-06-27T09:19:35.703 回答