rec*_*gle 6 python stack-overflow recursion
为什么/如何创建一个看似无限的循环?错误地,我认为这会导致某种形式的堆栈溢出类型错误.
i = 0
def foo () :
global i
i += 1
try :
foo()
except RuntimeError :
# This call recursively goes off toward infinity, apparently.
foo()
foo()
print i
Run Code Online (Sandbox Code Playgroud)
该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
>>>
Run Code Online (Sandbox Code Playgroud)
如果你想耗尽内存,请尝试消耗更多内存.
>>> def foo(l):
... l = l * 100
... foo(l)
...
>>> foo(["hello"])
Traceback (most recent call last):
...
File "<stdin>", line 2, in foo
MemoryError
>>>
Run Code Online (Sandbox Code Playgroud)
如果将代码更改为
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()
Run Code Online (Sandbox Code Playgroud)
您将观察到输出在 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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
415 次 |
| 最近记录: |