Это ограничение применяется не только к циклам for
, но и ко всем другим блокам потока управления. Ограничение на количество вложенных блоков потока управления определяется внутри кода .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 есть это конкретное ограничение и почему они не могут от него избавиться, дал Майкл Хадсон в письме из списка рассылки Python 2004 г.:
Точно. Это связано с «стеком блоков», очень внутренней деталью реализации Python. Мы хотели бы избавиться от него (нет, потому что хотим, чтобы люди писали код с более чем 20 вложенными циклами for :-), но это не особенно легко (наконец: блоки — самая большая проблема) .
Обратите внимание, что в Python 2.6 и ниже нарушение максимального количества вложенных циклов привело бы к SystemError
, а не SyntaxError
. Однако это было изменено в Python 3 и исправлено обратно в Python 2.7, поэтому вместо этого будет поднято SyntaxError
. Это было задокументировано в #issue 27514:
Проблема № 27514: слишком много статически вложенных блоков сделать SyntaxError вместо SystemError.
Причину такого изменения типов исключений указал Сергей Сторчака:
[...] SystemError не является исключением, которое следует вызывать. SystemError предназначена для ошибок, которые не могут возникнуть в обычном случае. Это должно быть вызвано только неправильным использованием C API или взломом внутренних компонентов Python. Я думаю, что SyntaxError больше подходит в этом случае [...].
person
Christian Dean
schedule
07.07.2017
if
. 20 вложенныхif
являются менее надуманным примером, чем 20 вложенныхfor
. Аргумент, занимающий слишком много времени, к ним не относится. - person Federico Poloni   schedule 08.07.2017