Ответ 1
Этот предел применяется не только к циклам 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;
}
Более конкретный ответ о том, почему Python имеет этот specfic-предел и почему он не может избавиться от него, был предоставлен Майкл Хадсон в списке рассылки Python 2004 года письмо:
Пятно включено. Это связано с "blockstack", очень внутренним подробно для реализации Python. Мы хотели бы избавиться от него (не потому что мы хотим, чтобы люди пишем код с более чем 20 вложенными для петли:-), но это не особенно легко (наконец: блоки - это самая большая проблема).
Обратите внимание, что в Python 2.6 и ниже разрыв максимального числа вложенных циклов вызовет SystemError
не a SyntaxError
. Это было изменено, однако, на Python 3 и исправлено до Python 2.7, поэтому вместо него будет создан SyntaxError
. Это было описано в # issue 27514:
Проблема # 27514: Сделать слишком много статически вложенных блоков синтаксисом вместо SystemError.
Причина этого изменения в типах исключений была дана Serhiy Storchaka:
[...] SystemError не является исключением, которое должно быть поднято. SystemError - это ошибки, которые невозможно выполнить в обычном случае. Это должно быть вызвано неправильным использованием API C или взломом внутренних компонентов Python. Я думаю, что SyntaxError более подходит в этом случае [...].