Python)の静的にネストされたブロックの数は20に制限されています。つまり、19個のfor
ループをネストすることは問題ありません(時間がかかりすぎますが、O(n^19)
非常識ですが)、20をネストすると失敗します:
SyntaxError: too many statically nested blocks
そのような制限がある根本的な理由は何ですか?制限を増やす方法はありますか?
この制限は、for
ループだけでなく、他のすべての制御フローブロックにも適用されます。ネストされた制御フローブロックの数の制限は、CO_MAXBLOCKS
という名前の定数で code.h 内で定義されます。
#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;
}
Pythonにこの特定の制限がある理由と、それを取り除くことができない理由に関するより具体的な答えは、 2004年のマイケルハドソンPythonメーリングリストの手紙 :
スポットオン。これは、Pythonの実装の内部的な詳細である「ブロックスタック」に関係しています。それを取り除きたい(not20を超えるネストされたforループでコードを記述できるようにしたいので:-)最大の問題です)。
Python 2.6以前では、ネストされたループの最大数を壊すと、SystemError
ではなくSyntaxError
が発生することに注意してください。ただし、これはPython 3で変更され、Python 2.7にバックパッチされるため、代わりにSyntaxError
が発生します。これは #issue 27514 で文書化されました。
問題#27514:静的にネストされたブロックが多すぎると、SystemErrorではなくSyntaxErrorになります。
例外タイプのこの変更の理由は Serhiy Storchaka によって与えられました:
[...] SystemErrorは発生する例外ではありません。 SystemErrorは、通常のケースでは発生しないエラー用です。 C APIの誤った使用またはPython内部のハッキングによってのみ発生します。この場合、SyntaxErrorの方が適切だと思います[...]。
これは blockstack
と関係があり、これはバイトコードアドレスのスタックであり、ループや例外などのコードブロックを実行するために使用されます。
Cのバージョン(C99より古い)がこの制限を20
に設定し、CPythonインタープリターはCで構築されているため、 同じ規則に従っています :
#define CO_MAXBLOCKS 20 /* Max static block nesting within a function */
定数20
は慣例に従って設定されているようで、それ以上のものはありません。
[リンク提供:クリスチャンディーン。]
慣習の議論が納得できない場合は、The Zen of Pythonを見てください:
In [4]: import this
The Zen of Python, by Tim Peters
...
Flat is better than nested.
...
この値はハードコードされた定数であるため、プログラムで有効に変更する唯一の方法は、pythonディストリビューションを再構築し、新しいビルドでスクリプトを実行することです。
こちらの回答をご覧ください: too many statically nested blocks python python構文に組み込まれているため、増やすことはできません。制限はあらゆる種類に適用されますコードスタック(例外、ループなど)であり、設計者による決定です(おそらくメモリ使用量を適切に保つためです)。1つの奇妙なことは、ここで: https://github.com/python /cpython/blob/6f0eb93183519024cb360162bdd81b9faec97ba6/Include/code.h#L95 関数内の20が最大数であると言いますが、私は関数内ではなくforループの23をネストしようとしましたが、それでもエラーが発生します。