python - 为什么 Python 对可以嵌套的静态 block 的数量有限制?

标签 python nested-loops language-implementation

Python 中的静态嵌套 block 数限制为 20 个。 也就是说,嵌套 19 个 for 循环会很好(虽然非常耗时;O(n^19) 太疯狂了),但是嵌套 20 个会失败:

SyntaxError: too many statically nested blocks

有这样一个限制的根本原因是什么? 有没有办法提高上限?

最佳答案

此限制不仅适用于 for 循环,还适用于所有其他控制流 block 。嵌套控制流 block 的数量限制在 code.h 内部定义。使用名为 CO_MAXBLOCKS 的常量:

#define CO_MAXBLOCKS 20 /* Max static block nesting within a function */

此常量用于设置 Python 用于执行名为 blockstack 的异常和循环的堆栈的最大大小。此限制适用于所有框架对象,并显示在 frameobject.h 中。 :

int blockstack[CO_MAXBLOCKS];       /* Walking the 'finally' blocks */

此限制的最可能原因是在执行嵌套 block 时将内存使用量保持在正常水平。它可能类似于 the limit Python imposes on recursive calls .这个限制可以在 compile.c 中看到。 :

if (c->u->u_nfblocks >= CO_MAXBLOCKS) {
    PyErr_SetString(PyExc_SyntaxError,
                    "too many statically nested blocks");
    return 0;
}

Michael Hudson in a 2004 Python mailing list letter 给出了关于 Python 为什么有这个特定限制以及为什么他们无法摆脱它的更具体的答案。 :

Spot on. This has to do with the 'blockstack', very much an internal detail to Python's implementation. We'd like to get rid of it (not because we want to let people write code with more than 20 nested for loops :-) but it's not especially easy (finally: blocks are the biggest problem).

请注意,在 Python 2.6 及更低版本中,打破最大嵌套循环数会导致 SystemError 而不是 SyntaxError。然而,这在 Python 3 中被更改并回补到 Python 2.7,因此将引发 SyntaxError 。这记录在 #issue 27514 :

Issue #27514: Make having too many statically nested blocks a SyntaxError instead of SystemError.

Serhiy Storchaka 给出了异常类型变化的原因。 :

[...] SystemError is not an exception that should be raised. SystemError is for errors that can't be occurred in normal case. It should only be caused by incorrect use of C API or hacking Python internals. I think SyntaxError is more appropriate in this case [...].

关于python - 为什么 Python 对可以嵌套的静态 block 的数量有限制?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44972719/

相关文章:

python - 如何模拟单例类方法

performance - 使用嵌套 for 循环的 Perl 脚本性能缓慢

haskell - G-machine,(非)严格上下文 - 为什么 case 表达式需要特殊处理

python - django 表单不显示或对象不带参数错误

python - 从电话号码字符串中删除不需要的字符

Python boolean 比较

javascript - 为什么这些嵌套的 forEach 循环会这样?

Julia - 继续外循环

arrays - 用于共享数组子范围的智能垃圾收集器?

python - 为什么 CPython Dicts 不受负一和负二哈希值的影响