繁体   English   中英

未达到Python最大递归

[英]Python maximum recursion not reached

当我运行以下程序时,为什么未达到sys.getrecursionlimit()的最大递归[在我的情况下,运行Ubuntu 18.04时为1000]。

import sys

global count

print(f'sys recursion limit is: {sys.getrecursionlimit()}')

count = 0
def foo(x):
    global count
    if x == 1:
        return 1
    else:
        count += 1
        return x + foo(x - 1)

x = 982
print(f'answer of foo({x}) = {foo(x)}, count = {count}')

x = 982结果

sys recursion limit is: 1000
answer of foo(982) = 482653, count = 981

但是当x = 983出现RecursionError

sys recursion limit is: 1000
Traceback (most recent call last):
  File "/home/bvermeulen/.vscode/extensions/ms-python.python-2019.9.34911/pythonFiles/lib/python/ptvsd/_vendored/pydevd/_pydevd_bundle/pydevd_frame.py", line 562, in trace_dispatch
    cmd = main_debugger.cmd_factory.make_io_message(info.pydev_message + os.linesep, '1')
  File "/home/bvermeulen/.vscode/extensions/ms-python.python-2019.9.34911/pythonFiles/lib/python/ptvsd/_vendored/pydevd/_pydevd_bundle/pydevd_net_command_factory_json.py", line 253, in make_io_message
    return NetCommand(CMD_WRITE_TO_CONSOLE, 0, event, is_json=True)
  File "/home/bvermeulen/.vscode/extensions/ms-python.python-2019.9.34911/pythonFiles/lib/python/ptvsd/_vendored/pydevd/_pydevd_bundle/pydevd_net_command.py", line 57, in __init__
    text = json.dumps(as_dict)
  File "/home/bvermeulen/.pyenv/versions/3.7.4/lib/python3.7/json/__init__.py", line 231, in dumps
    return _default_encoder.encode(obj)
  File "/home/bvermeulen/.pyenv/versions/3.7.4/lib/python3.7/json/encoder.py", line 199, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "/home/bvermeulen/.pyenv/versions/3.7.4/lib/python3.7/json/encoder.py", line 257, in iterencode
    return _iterencode(o, 0)
RecursionError: maximum recursion depth exceeded while encoding a JSON object
Traceback (most recent call last):
  File "/home/bvermeulen/.vscode/extensions/ms-python.python-2019.9.34911/pythonFiles/ptvsd_launcher.py", line 43, in <module>
    main(ptvsdArgs)
  File "/home/bvermeulen/.vscode/extensions/ms-python.python-2019.9.34911/pythonFiles/lib/python/ptvsd/__main__.py", line 432, in main
    run()
  File "/home/bvermeulen/.vscode/extensions/ms-python.python-2019.9.34911/pythonFiles/lib/python/ptvsd/__main__.py", line 316, in run_file
    runpy.run_path(target, run_name='__main__')
  File "/home/bvermeulen/.pyenv/versions/3.7.4/lib/python3.7/runpy.py", line 263, in run_path
    pkg_name=pkg_name, script_name=fname)
  File "/home/bvermeulen/.pyenv/versions/3.7.4/lib/python3.7/runpy.py", line 96, in _run_module_code
    mod_name, mod_spec, pkg_name, script_name)
  File "/home/bvermeulen/.pyenv/versions/3.7.4/lib/python3.7/runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "/home/bvermeulen/Python/stackoverflow/recursion.py", line 18, in <module>
    print(f'answer of foo({x}) = {foo(x)}, count = {count}')
  File "/home/bvermeulen/Python/stackoverflow/recursion.py", line 15, in foo
    return x + foo(x - 1)
  File "/home/bvermeulen/Python/stackoverflow/recursion.py", line 15, in foo
    return x + foo(x - 1)
  File "/home/bvermeulen/Python/stackoverflow/recursion.py", line 15, in foo
    return x + foo(x - 1)
  [Previous line repeated 977 more times]
  File "/home/bvermeulen/Python/stackoverflow/recursion.py", line 14, in foo
    count += 1
  File "/home/bvermeulen/Python/stackoverflow/recursion.py", line 14, in foo
    count += 1
  File "/home/bvermeulen/.vscode/extensions/ms-python.python-2019.9.34911/pythonFiles/lib/python/ptvsd/_vendored/pydevd/_pydevd_bundle/pydevd_frame.py", line 562, in trace_dispatch
    cmd = main_debugger.cmd_factory.make_io_message(info.pydev_message + os.linesep, '1')
  File "/home/bvermeulen/.vscode/extensions/ms-python.python-2019.9.34911/pythonFiles/lib/python/ptvsd/_vendored/pydevd/_pydevd_bundle/pydevd_net_command_factory_json.py", line 253, in make_io_message
    return NetCommand(CMD_WRITE_TO_CONSOLE, 0, event, is_json=True)
  File "/home/bvermeulen/.vscode/extensions/ms-python.python-2019.9.34911/pythonFiles/lib/python/ptvsd/_vendored/pydevd/_pydevd_bundle/pydevd_net_command.py", line 57, in __init__
    text = json.dumps(as_dict)
  File "/home/bvermeulen/.pyenv/versions/3.7.4/lib/python3.7/json/__init__.py", line 231, in dumps
    return _default_encoder.encode(obj)
  File "/home/bvermeulen/.pyenv/versions/3.7.4/lib/python3.7/json/encoder.py", line 199, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "/home/bvermeulen/.pyenv/versions/3.7.4/lib/python3.7/json/encoder.py", line 257, in iterencode
    return _iterencode(o, 0)
RecursionError: maximum recursion depth exceeded while encoding a JSON object

如果我在Pycharm中打开一个干净的文件并使用print_stack打印出堆栈跟踪:

import traceback

traceback.print_stack()

我得到:

File "C:\Program Files\JetBrains\PyCharm Community Edition 2019.1.3\helpers\pydev\pydevconsole.py", line 483, in <module>
    pydevconsole.start_client(host, port)
File "C:\Program Files\JetBrains\PyCharm Community Edition 2019.1.3\helpers\pydev\pydevconsole.py", line 411, in start_client
    process_exec_queue(interpreter)
File "C:\Program Files\JetBrains\PyCharm Community Edition 2019.1.3\helpers\pydev\pydevconsole.py", line 258, in process_exec_queue
    more = interpreter.add_exec(code_fragment)
File "C:\Program Files\JetBrains\PyCharm Community Edition 2019.1.3\helpers\pydev\_pydev_bundle\pydev_console_utils.py", line 151, in add_exec
    more = self.do_add_exec(code_fragment)
File "C:\Program Files\JetBrains\PyCharm Community Edition 2019.1.3\helpers\pydev\pydevconsole.py", line 84, in do_add_exec
    command.run()
File "C:\Program Files\JetBrains\PyCharm Community Edition 2019.1.3\helpers\pydev\_pydev_bundle\pydev_console_types.py", line 35, in run
    self.more = self.interpreter.runsource(text, '<input>', symbol)
File "C:\Users\slomi\AppData\Local\Programs\Python\Python37-32\lib\code.py", line 74, in runsource
    self.runcode(code)
File "C:\Users\slomi\AppData\Local\Programs\Python\Python37-32\lib\code.py", line 90, in runcode
    exec(code, self.locals)
File "<input>", line 1, in <module>
File "C:\Program Files\JetBrains\PyCharm Community Edition 2019.1.3\helpers\pydev\_pydev_bundle\pydev_umd.py", line 197, in runfile
    pydev_imports.execfile(filename, global_vars, local_vars)  # execute the script
File "C:\Program Files\JetBrains\PyCharm Community Edition 2019.1.3\helpers\pydev\_pydev_imps\_pydev_execfile.py", line 18, in execfile
    exec(compile(contents+"\n", file, 'exec'), glob, loc)
File "C:/Users/slomi/PycharmProjects/chat/cr.py", line 3, in <module>
    traceback.print_stack()

因此,似乎取决于您的环境,甚至在您自己的代码运行之前,堆栈中就已经有东西了。 在我位于Pycharm的计算机上,您的代码实际上在x = 986处失败,并且在注释中,有人指出,在在线IDE(运行情况可能少于Pycharm)上,它在x = 999处失败。 看来这取决于您的IDE在代码运行之前在后台进行的操作。

在调用方法foo之前,堆栈中已经存在其他调用,例如

主要->打印-> ...

您可以在堆栈跟踪中看到许多函数调用。 如果完整的堆栈大小(在foo中输入之前的调用数+ foo调用数)达到了递归限制,则将引发错误。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM