Python中静态嵌套块的数量限制为20个。
也就是说,嵌套19 for
循环会很好(虽然过于耗时; O(n^19)
是疯了),但嵌套20将失败:
SyntaxError: too many statically nested blocks
有这样限制的根本原因是什么? 有没有办法增加限额?
答案 0 :(得分:73)
此限制不仅适用于for
循环,也适用于所有其他控制流程块。嵌套控件流块数量的限制在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 */
此限制的最可能原因是在执行嵌套块时将内存使用保持在理智水平。它可能与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有这个特定的限制以及为什么它们无法摆脱它?
点亮。这与' blockstack'非常相关 详细介绍了Python的实现。我们想摆脱它(不是 因为我们想让人们编写超过20个嵌套的代码 循环:-)但它不是特别容易(最后:块是 最大的问题)。
请注意,在Python 2.6及更低版本中,打破嵌套循环的最大数量会导致SystemError
而不是SyntaxError
。然而,在Python 3中对此进行了更改,并将其修补为Python 2.7,因此将引发SyntaxError
。这在#issue 27514:
问题#27514:使有太多静态嵌套的块成为SyntaxError 而不是SystemError。
异常类型更改的原因由Serhiy Storchaka :
提供[...] SystemError不是应该引发的异常。 SystemError用于在正常情况下无法发生的错误。它应该只是由于错误地使用C API或黑客攻击Python内部造成的。我认为在这种情况下,SyntaxError更合适[...]。
答案 1 :(得分:21)
这与blockstack
有关,它是字节代码地址的堆栈,用于执行循环和异常等代码块。
恰好有一个版本的C(早于C99)将此限制设置为20
,并且由于CPython解释器是使用C构建的,the same convention has been followed:
#define CO_MAXBLOCKS 20 /* Max static block nesting within a function */
常量20
似乎是在惯例之外设置的,仅此而已。
[链接由Christian Dean提供。]
如果约定的论点不具说服力,那么看一下 Python的禅宗:
In [4]: import this
The Zen of Python, by Tim Peters
...
Flat is better than nested.
...
由于此值是一个硬编码常量,因此将其更改为在程序中生效的唯一方法是重建python发行版并在新版本上运行脚本。
导航至cpython/Include/code.h
将CO_MAXBLOCKS
的值更改为大于20的
重新编译Python(禁用测试,they'll complain)
答案 2 :(得分:3)
请在此处查看答案:too many statically nested blocks python 你不能增加它,因为它内置于python语法。该限制适用于任何类型的代码堆栈(异常,循环等),并且是设计者的决定(可能是为了保持内存使用的合理性)。 一个奇怪的事情是:https://github.com/python/cpython/blob/6f0eb93183519024cb360162bdd81b9faec97ba6/Include/code.h#L95它表示20是函数中的最大数字。但我只是尝试嵌套23 for循环,而不是在函数内部,你仍然得到错误。