Поэтому, играя с Python, я заметил, что в основном нет ограничений на размер стека программы (продолжал выполнять операции с питанием для числа, точность оставалась идеальной даже после того, как дошли до тысяч цифр). Это заставляет меня задуматься: а что, если я случайно попаду в бесконечный рекурсивный цикл в Python? Компилятор заметит и выдаст ошибку переполнения стека? Или программа просто вылетит? Сгорел бы мой процессор? Честно говоря, мне не хотелось бы это проверять.
Как Python обрабатывает бесконечную рекурсию?
Ответы (2)
Я обещаю, что ни один современный компьютер не сгорит из-за пользовательского кода. Попробуйте сами:
def recurseInfinitely( n ):
recurseInfinitely(n+1)
recurseInfinitely(0)
Быстрый запуск этой программы дает результат:
[...]
recurseInfinitely(n+1)
File "so.py", line 2, in recurseInfinitely
recurseInfinitely(n+1)
File "so.py", line 2, in recurseInfinitely
recurseInfinitely(n+1)
RuntimeError: maximum recursion depth exceeded
Вы можете поймать ошибку и проверить значение n
:
def recurseInfinitely( n ):
try:
recurseInfinitely(n+1)
except RuntimeError:
print "We got to level %s before hitting the recursion limit."%n
И получить:
Мы добрались до 997-го уровня до того, как достигли лимита рекурсии.
Python (по крайней мере, эталонная реализация) этого не делает - у вас не может быть бесконечного рекурсивного цикла, как в некоторых функциональных языках. Он вызовет исключение, когда рекурсия достигнет глубины около 1000 (по умолчанию это можно изменить с помощью sys.setrecursionlimit). Так что да, программа вылетит.
В отличие от большинства функциональных языков Python не требует оптимизации хвостовой рекурсии. Осмелюсь сказать, что все рекурсивные алгоритмы должны быть преобразованы в итеративную форму в Python (это тривиально), иначе ваша реализация не совсем правильная.
Пользователь larsmans прокомментировал, что встроенный предел глубины рекурсии достаточно хорош для большинства практических алгоритмов, но итеративная форма обычно работает лучше - причина в том, что вызовы функций в Python обходятся дорого.
У вас может быть цикл взлетно-посадочной полосы в Python, если вы зациклите генератор, который никогда не генерирует StopIteration. Он будет работать до тех пор, пока (и если) вы не завершите процесс или он не исчерпает ресурсы компьютера (иногда приводя к остановке машины).