for
循环是可以的(虽然非常耗时;O(n^19)
是无法承受的),但是嵌套20个将会失败并出现以下错误信息:SyntaxError: too many statically nested blocks
为什么有这样的限制?是否有办法增加限制?
for
循环是可以的(虽然非常耗时;O(n^19)
是无法承受的),但是嵌套20个将会失败并出现以下错误信息:SyntaxError: too many statically nested blocks
为什么有这样的限制?是否有办法增加限制?
for
循环,还适用于所有其他控制流块。嵌套控制流块的数量限制在 code.h 中定义,使用一个名为 CO_MAXBLOCKS
的常量:#define CO_MAXBLOCKS 20 /* Max static block nesting within a function */
blockstack
。这个限制适用于所有帧对象,并在frameobject.h中显示:int blockstack[CO_MAXBLOCKS]; /* Walking the 'finally' blocks */
这个限制最有可能是为了在执行嵌套块时保持内存使用在一个合理的水平。这很可能类似于Python对递归调用施加的限制。这个限制可以在compile.c中看到被执行:
if (c->u->u_nfblocks >= CO_MAXBLOCKS) {
PyErr_SetString(PyExc_SyntaxError,
"too many statically nested blocks");
return 0;
}
关于为什么Python有这个特定的限制,以及为什么他们不能摆脱它,Michael Hudson在2004年的Python邮件列表中给出了更具体的答案:
太准确了。这与Python实现的“块栈”有关,这是Python实现的一个内部细节。我们想摆脱它(不是因为我们想让人们编写超过20个嵌套的for循环的代码 :-) ,但这并不是特别容易(最后:块是最大的问题)。
请注意,在Python 2.6及以下版本中,打破最大嵌套循环数会导致SystemError
而不是SyntaxError
。然而,这在Python 3中已经改变,并向Python 2.7进行了回溯,以便引发SyntaxError
。这在#issue 27514中有所记录:
问题 #27514: 当有太多静态嵌套块时,将其视为SyntaxError而不是SystemError。
这种异常类型的更改原因由Serhiy Storchaka给出:
[...] SystemError并不是应该被引发的异常。SystemError用于在正常情况下无法发生的错误。它只能由错误使用C API或黑客Python内部引起。我认为在这种情况下,SyntaxError更加合适[...]。
CO_MAXBLOCKS
然后重新编译,理论上你可以有超过二十个嵌套块。 - Christian Dean这与blockstack
有关,它是一个字节码地址的堆栈,用于执行代码块,如循环和异常。
恰好C语言的一个版本(早于C99)将此限制设置为20
,由于CPython解释器是使用C构建的,因此遵循了同样的约定:
#define CO_MAXBLOCKS 20 /* Max static block nesting within a function */
常数20
似乎是根据惯例设置的,除此之外没有其他意义。
[链接来自Christian Dean。]
如果惯例的论点不令人信服,那么看一下 The Zen of Python:
In [4]: import this
The Zen of Python, by Tim Peters
...
Flat is better than nested.
...
由于这个值是硬编码常量,改变它影响你的程序的唯一方法是重建你的Python发行版并在新版本上运行你的脚本。
if
。20个嵌套的if
比20个嵌套的for
更不刻意。"过度耗时"的论点不适用于它们。 - Federico Poloni