当前位置: 首页 > 面试题库 >

为什么Python对可嵌套的静态块数有限制?

谭研
2023-03-14
问题内容

Python中静态嵌套的块数限制为20。也就是说,嵌套19个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 */

此常数用于设置Python用于执行名为的异常和循环的堆栈的最大大小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;
}

Michael Hudson在2004年的Python邮件列表信中给出了关于Python为什么有此特定限制以及为什么他们不能摆脱它的更具体的答案:

发现。这与“块栈”有关,这在很大程度上是Python实现的内部细节。我们想摆脱它( 不是
因为我们想让人们编写带有20多个嵌套的for循环的代码:-),但这并不是特别容易(最终:块是最大的问题)。

请注意,在Python 2.6及更低版本中,打破嵌套循环的最大数量将导致SystemError不为SyntaxError。但是,在Python
3中对此进行了更改,并重新修补了Python 2.7,因此SyntaxError将引发a 。在#issue
27514
中对此进行了记录:

问题#27514:使太多静态嵌套的块成为SyntaxError而不是SystemError。

Serhiy Storchaka给出了异常类型发生这种变化的原因:

[…] SystemError不是应该引发的异常。SystemError适用于正常情况下不会发生的错误。只能由错误使用C
API或入侵Python内部构件引起。我认为在这种情况下[…] SyntaxError更合适。



 类似资料:
  • 问题内容: 我正在查看Java代码,并注意到它使用了静态嵌套类。 使用静态嵌套类而不是普通内部类的原因是什么? 我能想到的唯一原因是Entry不能访问实例变量,因此从OOP的角度来看,它具有更好的封装性。 但是我认为可能还有其他原因,也许是性能。可能是什么? 注意。我希望我的术语正确,可以将其称为静态内部类,但是我认为这是错误的:http : //java.sun.com/docs/books/t

  • 问题内容: 什么是静态嵌套类?静态和非静态嵌套类有什么区别? 问题答案: 静态内部类是嵌套在具有修饰符的另一个类中的类。除了可以访问在其内部定义的类的私有成员之外,它与顶级类几乎相同。 类是静态内部类。类是一个非静态的内部类。两者之间的区别是,非静态内部类的实例被永久连接到的实例-你不能创建一个没有。不过,您可以独立创建对象。 中的代码,并且都可以访问x; 不允许使用其他代码。

  • 但是为什么在下面的情景中允许静态嵌套类对象的实例化呢? 为什么我们可以创建内部类的对象,如果它被标记为静态的?

  • 问题内容: 我已经开始学习用于Android应用程序开发的Java语言。 根据我对静态类的理解,我们无法实例化静态类的对象。 但是,为什么在随后的情况下允许实例化静态嵌套类对象? 如果将内部类的对象标记为静态,为什么我们可以创建它呢? 问题答案: 根据我对静态类的理解,我们无法实例化静态类的对象。 您对“静态类”的含义的理解不正确。基本上, Java中 的“静态类” 是嵌套类,它没有对包含类的实例

  • 问题内容: 另外,在网上可以找到许多创建静态变量的解决方案。(尽管我还没有看到我喜欢的一个。) 为什么Python不支持方法中的静态变量?这被认为是非Python的,还是与Python的语法有关? 编辑: 我专门询问了 为什么 进行设计决策,但我没有提供任何代码示例,因为我想避免解释来模拟静态变量。 问题答案: 忽略这一点的想法是,静态变量仅在以下两种情况下才有用:何时真正应该使用类以及何时真正应

  • 问题内容: 我刚刚在我们的代码库中找到了一个静态嵌套接口。 我以前从未见过。原始开发人员遥不可及。因此,我不得不问: 静态接口背后的语义是什么?如果我删除,会发生什么变化static?为什么有人会这样做? 问题答案: 上例中的static关键字是多余的(嵌套接口自动为“ static”),可以删除而不会影响语义;我建议将其删除。接口方法上的“公共”和接口字段上的“公共最终”也是如此-修饰符是多余的