简体   繁体   English

未达到Python最大递归

[英]Python maximum recursion not reached

Why is the maximum recursion of sys.getrecursionlimit() [which is 1000 in my case running Ubuntu 18.04] not reached when I run the following program. 当我运行以下程序时,为什么未达到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}')

result with x = 982 x = 982结果

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

but with x = 983 I get a RecursionError 但是当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

If I open a clean file in Pycharm and print out a stack trace using print_stack : 如果我在Pycharm中打开一个干净的文件并使用print_stack打印出堆栈跟踪:

import traceback

traceback.print_stack()

I get: 我得到:

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()

So, it seems that depending on your environment, there will be stuff already on the stack before your own code even runs. 因此,似乎取决于您的环境,甚至在您自己的代码运行之前,堆栈中就已经有东西了。 On my computer in Pycharm, your code actually fails at x = 986 , and in the comments, someone noted that on an online IDE (which presumably has less going on than Pycharm), it failed at x = 999 . 在我位于Pycharm的计算机上,您的代码实际上在x = 986处失败,并且在注释中,有人指出,在在线IDE(运行情况可能少于Pycharm)上,它在x = 999处失败。 It seems it depends on what your IDE has going on in the background before your code is run. 看来这取决于您的IDE在代码运行之前在后台进行的操作。

Before calling the method foo there is already other calls in the stack, like 在调用方法foo之前,堆栈中已经存在其他调用,例如

main -> print ->... 主要->打印-> ...

There are many functions calls you can see in your stacktrace. 您可以在堆栈跟踪中看到许多函数调用。 If the full stack size (number of calls before enter in foo + number of foo calls) reach your recursion limit so the error will be thrown. 如果完整的堆栈大小(在foo中输入之前的调用数+ foo调用数)达到了递归限制,则将引发错误。

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

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